From patchwork Mon Sep 27 11:42:20 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anup Patel X-Patchwork-Id: 12519635 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2A703C4332F for ; Mon, 27 Sep 2021 11:43:09 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 0F67C60F91 for ; Mon, 27 Sep 2021 11:43:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234299AbhI0Lop (ORCPT ); Mon, 27 Sep 2021 07:44:45 -0400 Received: from esa2.hgst.iphmx.com ([68.232.143.124]:8739 "EHLO esa2.hgst.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234226AbhI0Lo3 (ORCPT ); Mon, 27 Sep 2021 07:44:29 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=wdc.com; i=@wdc.com; q=dns/txt; s=dkim.wdc.com; t=1632742972; x=1664278972; h=from:to:cc:subject:date:message-id:in-reply-to: references:content-transfer-encoding:mime-version; bh=bQpPLSGwOWwfFfy86WpMrIpcl7VNHao4rLyj/IjeMjw=; b=Z045+NMCKT3dmFpLydn7JRXhVSxzmyA9qwPKhlVHHnymaABirvPvDj3D txuc46l5mbET6tgd4PwoUeUstQlv9N5UunA7uElW8UruL++C9SMKVNAL5 b8r1JTvmWCt961OpZhXKhbzc9zcXpK6OJPX02sDnMOWoCepOHNDXicS8k WXuGWRZ4FGNxPiHypJV71xQHcQCH29sr/JGHAOqAn6iq4cs3+Ig9/wi19 4CpITQBqILe6VEnVb6SJR9cpv1rEoZG4Y1mj6qxNCs/n6tu4z2TXHNvd5 HaqvZP938LrXx+mqxzSMBOGehbQLvJ6KezV5MMkpVkMGhggEm6r10GbRF w==; X-IronPort-AV: E=Sophos;i="5.85,326,1624291200"; d="scan'208";a="284861958" Received: from mail-dm6nam10lp2103.outbound.protection.outlook.com (HELO NAM10-DM6-obe.outbound.protection.outlook.com) ([104.47.58.103]) by ob1.hgst.iphmx.com with ESMTP; 27 Sep 2021 19:42:51 +0800 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=N78znMPhA+vm/Qw2+DinnuEZEe+tajt3Uha3YPjfJb1pemquZlJlHrHswCfiS1u+bYvbZU9U5kkQgf82BELaHSSuXju4vJgau7PSJIpa71NjsVqyg5ZzI7hQK5R1i0gzmX8mpwudwnxioKLGIytLEFRnkGE2TFn4UtTG8pp+JB2j5lnei5T2gSsM4XSdASZtKf1FnEU96RNoLMdKyAIiHPMt58Fh49JHkLgDIeTfZZbVx/JMKab1JSFKk6GBnWclY6BfKOs2mzoWLzc/52UT/Em8q3SwaKVbKvYlWP5GMA1pW9xNI0mNyxWtdzCe2ZAuDxaolU/06xPPIOg0nUDDmg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=82K4Te6rGNy+YzDB8cuMb0i9iuQlOUHdvo+QqIXIz5U=; b=cm36ZV6CpjMG0D02Xtii0+P/ugX9F0WpfpEDTizqI8uIu698oDYwgsJo9eW2OvOyK6vlWl8V3PsZynu8BGZi/JiylJDtrV8o7HgJ8xiAzrqkqxoSQTPZHMrVn768iimyhNlNWhVuaODTMGhfP+nVrez5QYA6XWUYRSPsjSHTfPcR4RcGuYRCgsswoWXIlGPN1aZVqNPSvTfEu+GHFmzyieM7EK+axgWTHFBX82CkOb5jApLJKBtl30MdF3Vruw6zbX/2nHbA4EUmB5GiYn6XnJhuiOGt4jPAypaP5qNIAXrPBWpAIGstUOV08UiZVQ7GRJLWC951vnO1m8esRIF9hw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=wdc.com; dmarc=pass action=none header.from=wdc.com; dkim=pass header.d=wdc.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sharedspace.onmicrosoft.com; s=selector2-sharedspace-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=82K4Te6rGNy+YzDB8cuMb0i9iuQlOUHdvo+QqIXIz5U=; b=kmXOy5utv6d9LBGbhQxedW2Q02I73NnvfC63T9bDBwvgTX0w8GcfneQV9tLGLEd70AbgZpcKwsLOvWDNXgDEjlN2UiIwUV0PINqBtsfWYZfVxaNh/jsL5aKThfGr2JbjYDSG0K7TnruuSXDuqgCA2TRlYnV1Sfk7hpQlaxn1AyY= Authentication-Results: kernel.org; dkim=none (message not signed) header.d=none;kernel.org; dmarc=none action=none header.from=wdc.com; Received: from CO6PR04MB7812.namprd04.prod.outlook.com (2603:10b6:303:138::6) by CO1PR04MB8236.namprd04.prod.outlook.com (2603:10b6:303:163::17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4544.14; Mon, 27 Sep 2021 11:42:49 +0000 Received: from CO6PR04MB7812.namprd04.prod.outlook.com ([fe80::6830:650b:8265:af0b]) by CO6PR04MB7812.namprd04.prod.outlook.com ([fe80::6830:650b:8265:af0b%6]) with mapi id 15.20.4544.021; Mon, 27 Sep 2021 11:42:49 +0000 From: Anup Patel To: Will Deacon Cc: Paolo Bonzini , Atish Patra , Alistair Francis , Anup Patel , kvm@vger.kernel.org, kvm-riscv@lists.infradead.org, Anup Patel Subject: [PATCH v9 1/8] update_headers: Sync-up ABI headers with Linux-5.15-rc2 Date: Mon, 27 Sep 2021 17:12:20 +0530 Message-Id: <20210927114227.1089403-2-anup.patel@wdc.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210927114227.1089403-1-anup.patel@wdc.com> References: <20210927114227.1089403-1-anup.patel@wdc.com> X-ClientProxiedBy: MA1PR01CA0173.INDPRD01.PROD.OUTLOOK.COM (2603:1096:a01:d::14) To CO6PR04MB7812.namprd04.prod.outlook.com (2603:10b6:303:138::6) MIME-Version: 1.0 Received: from wdc.com (122.179.75.205) by MA1PR01CA0173.INDPRD01.PROD.OUTLOOK.COM (2603:1096:a01:d::14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4544.14 via Frontend Transport; Mon, 27 Sep 2021 11:42:47 +0000 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 359946c5-5e4c-4df2-51a3-08d981abee8e X-MS-TrafficTypeDiagnostic: CO1PR04MB8236: X-MS-Exchange-Transport-Forked: True X-Microsoft-Antispam-PRVS: WDCIPOUTBOUND: EOP-TRUE X-MS-Oob-TLC-OOBClassifiers: OLM:2276; X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: N2VTwsL5c20PLp9jzplnWDrRMRtaIej8TdYENq41Ww8S6s3zQ362Ygt58AZ0q4MOsvdfdtmY6QHDYZpeLqsbVziRppfW7+lPYdBoKwcPZgdRCBOD9tY+7Ya1qGKu7QiNFiMjePekuiKp14dbpyQXVSTqBpcr0luiNIoaqpsCyeiYg1js64mtEUTJ7HCmw4eXPiN9qb67/Grr/2y7vawsi/niq+YbsmDabZZdU7qZ2VYD9BJ8II9Vz9OxM8gQIBMDGsKO0CBwGEpxQi1ONiKdHMuDjs1ZG8Xs3QP2UO2jah5sIEedTY1vC3l2jwLHOZJTOs6M/WFkRlzWZwlUmQB2O7iZL5KFI0ZwGCnKsfKYOC65/+lSjF6IK68+Jw85GNHZ9cqr+aXwHJiD6RcgJJbXSp3F1UET+/GHiCkEHlXroD8JwAzlbd6GeB5+owyNIxKhhPYls/za5gcJa9mlw94gG5ymBgKYAebL62m9VRBR2qZnY0/lpczPzMka6p3rDLA/oSH/RyOf4VFBoR4+wz4pV51pqLsWOb9RSIPAQlS2ILZoyj9JRVCmoaLbUozzunv2SZe6/JgMQdO2yWzFeRxTxlTIQe1FyZoPRqleKHAENNRhvqeV4jzstc2HZoEYHxSnAw7CBJbwwI8LE9YNrmEdI798qtCai9T36zM5mwinmQbNIpQXXphWqeeQj/08UJt8 X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:CO6PR04MB7812.namprd04.prod.outlook.com;PTR:;CAT:NONE;SFS:(4636009)(366004)(15650500001)(6916009)(316002)(66946007)(44832011)(38100700002)(54906003)(186003)(55016002)(38350700002)(8936002)(508600001)(7696005)(6666004)(1076003)(36756003)(66476007)(66556008)(4326008)(2616005)(5660300002)(86362001)(2906002)(8676002)(8886007)(52116002)(26005)(83380400001)(30864003)(956004);DIR:OUT;SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: VKj705FYLKYM0pR5xtZRdYcfa1kz5pJy+VtZJfFM27G3QCSOj3VixV1dM7Y4w+m35ZPIeUvnFRWPuTF7zIpEbtKy28gVzzMy56bTKaGdotmQiw/fHTaSEkyNIISSKgMxHBnJMK/m3DUJoTLAMcuxwSfMrDFdXiRQh/1rqOCnjLJtvqMy1EnM1QiQjEoIjlF8+AtZmrRkfSI1vobnl5Qn4Jl71/9Dfw2HS/XJsBL9zkXxV2ZdnqPKS/0iTuYJO94ZeyduNwvGTVjGI0jysC4bu26v4d7Te5uWqMUlGf+Gcl9078jnqXG23TphZwp90+obqEBobIhyF2n2lggnagfReZh9RigIEpYD/+irWhu7Qcyj8/27pUjvNVIM0ZVK09VXPR9eyNuQI7ZcNCXYvrXr8oqKE3RqPuWl92FfxKwmEirnX/K6D1truJWrb+b88i10Lw/g/2qya2uej6P/9lcaETHcKHgfTa3yfptFJJEBI8OdPQicl4jTyp4G0ujnrugbRkrhUpl2QuTDoXfKebwd4WDVTKjX9r8f0Rv4XY5904ovalB/+d8r7QkAtRxgTJfyPpQtu43xvLa7EVbrpI922PPDhN2WpGyKUrQ0NKCfT3S/3XyQdeQBj293qUL9IRRqgbUBPir5gmw+hMqvsB295GqBsfEywPr5itRFbBkq1/D87U3MVaXmykfrFtrYAwjr7zUiTjR+I0ZgYXSl14i/r7Uy1x04P5/nljIkoc5olPruXP7l/6dBWfklLqxWoFjyEG7da5s1lC/tSW7JHgAxpUkLgT5a5sAzrrtZMFYeWR5sGFsCB6bwCQ/QLKf6FVj+YBdeb1KN5y8M3M5HcyShUZ2SQQQdIirRBWo3kJKIlN8uxAXWjeLzehL8MDnw/SnO8WFdGrHpcsXK35XoLDbJcCg2Wl2xAdtedNr3Ec6izprd90ZpO8j2OrRFMOwdj/zRXfzLkAbHS+eNddY2VRUP+AyiJoOmfOQwYg45mdv9cjdU+7N7G/3rMeUHqZcpq4Id9f7k/JwZkoDrtZsD20HJKctt6S7VHyGCHMp5R52EVdrNhbIM/L6DoP1X3UTWnLAj+ASw03f2H++mQ0Q5IbDcIDWJEO6R+EpFt9OArzSEcJf8DxY4smgQfJ7TPjxsh1ERF4hT8XTvdoM5H4mmPqssozWCsfJ8thYK6AJu+smlqgYXYQcPC3Ed0Vl1Tchyyc4MPuOx9iIcM9+eyXyN6c1ybOFaEMt8hh4SMwOTZidfbhLpxFuokVcIPCjH39rE9SK7Bsb+Qey7J17ATTRPHOaudnRiLuD+csMiY39zpduEqnbGwptYv8Uk7AEtLYdczjm1 X-OriginatorOrg: wdc.com X-MS-Exchange-CrossTenant-Network-Message-Id: 359946c5-5e4c-4df2-51a3-08d981abee8e X-MS-Exchange-CrossTenant-AuthSource: CO6PR04MB7812.namprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 27 Sep 2021 11:42:49.4556 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: b61c8803-16f3-4c35-9b17-6f65f441df86 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: IxzkBgDYBz7Pqep+NNc15Rji1wnk11Enb3t9zp+UVbPDY8eOXvSE96llxcEdrr5E05p/6GWBA7LUgyo7t0Wzig== X-MS-Exchange-Transport-CrossTenantHeadersStamped: CO1PR04MB8236 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org We sync-up all ABI headers with Linux-5.15-rc2 so that RISC-V specfic changes in include/linux/kvm.h are available. Signed-off-by: Anup Patel --- arm/aarch64/include/asm/kvm.h | 56 ++++- include/linux/kvm.h | 423 +++++++++++++++++++++++++++++++++- powerpc/include/asm/kvm.h | 10 + x86/include/asm/kvm.h | 60 ++++- 4 files changed, 536 insertions(+), 13 deletions(-) diff --git a/arm/aarch64/include/asm/kvm.h b/arm/aarch64/include/asm/kvm.h index 9a50771..b3edde6 100644 --- a/arm/aarch64/include/asm/kvm.h +++ b/arm/aarch64/include/asm/kvm.h @@ -156,7 +156,19 @@ struct kvm_sync_regs { __u64 device_irq_level; }; -struct kvm_arch_memory_slot { +/* + * PMU filter structure. Describe a range of events with a particular + * action. To be used with KVM_ARM_VCPU_PMU_V3_FILTER. + */ +struct kvm_pmu_event_filter { + __u16 base_event; + __u16 nevents; + +#define KVM_PMU_EVENT_ALLOW 0 +#define KVM_PMU_EVENT_DENY 1 + + __u8 action; + __u8 pad[3]; }; /* for KVM_GET/SET_VCPU_EVENTS */ @@ -164,13 +176,25 @@ struct kvm_vcpu_events { struct { __u8 serror_pending; __u8 serror_has_esr; + __u8 ext_dabt_pending; /* Align it to 8 bytes */ - __u8 pad[6]; + __u8 pad[5]; __u64 serror_esr; } exception; __u32 reserved[12]; }; +struct kvm_arm_copy_mte_tags { + __u64 guest_ipa; + __u64 length; + void __user *addr; + __u64 flags; + __u64 reserved[2]; +}; + +#define KVM_ARM_TAGS_TO_GUEST 0 +#define KVM_ARM_TAGS_FROM_GUEST 1 + /* If you need to interpret the index values, here is the key: */ #define KVM_REG_ARM_COPROC_MASK 0x000000000FFF0000 #define KVM_REG_ARM_COPROC_SHIFT 16 @@ -219,10 +243,18 @@ struct kvm_vcpu_events { #define KVM_REG_ARM_PTIMER_CVAL ARM64_SYS_REG(3, 3, 14, 2, 2) #define KVM_REG_ARM_PTIMER_CNT ARM64_SYS_REG(3, 3, 14, 0, 1) -/* EL0 Virtual Timer Registers */ +/* + * EL0 Virtual Timer Registers + * + * WARNING: + * KVM_REG_ARM_TIMER_CVAL and KVM_REG_ARM_TIMER_CNT are not defined + * with the appropriate register encodings. Their values have been + * accidentally swapped. As this is set API, the definitions here + * must be used, rather than ones derived from the encodings. + */ #define KVM_REG_ARM_TIMER_CTL ARM64_SYS_REG(3, 3, 14, 3, 1) -#define KVM_REG_ARM_TIMER_CNT ARM64_SYS_REG(3, 3, 14, 3, 2) #define KVM_REG_ARM_TIMER_CVAL ARM64_SYS_REG(3, 3, 14, 0, 2) +#define KVM_REG_ARM_TIMER_CNT ARM64_SYS_REG(3, 3, 14, 3, 2) /* KVM-as-firmware specific pseudo-registers */ #define KVM_REG_ARM_FW (0x0014 << KVM_REG_ARM_COPROC_SHIFT) @@ -233,6 +265,15 @@ struct kvm_vcpu_events { #define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1_NOT_AVAIL 0 #define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1_AVAIL 1 #define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1_NOT_REQUIRED 2 + +/* + * Only two states can be presented by the host kernel: + * - NOT_REQUIRED: the guest doesn't need to do anything + * - NOT_AVAIL: the guest isn't mitigated (it can still use SSBS if available) + * + * All the other values are deprecated. The host still accepts all + * values (they are ABI), but will narrow them to the above two. + */ #define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2 KVM_REG_ARM_FW_REG(2) #define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_AVAIL 0 #define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_UNKNOWN 1 @@ -320,13 +361,18 @@ struct kvm_vcpu_events { #define KVM_ARM_VCPU_PMU_V3_CTRL 0 #define KVM_ARM_VCPU_PMU_V3_IRQ 0 #define KVM_ARM_VCPU_PMU_V3_INIT 1 +#define KVM_ARM_VCPU_PMU_V3_FILTER 2 #define KVM_ARM_VCPU_TIMER_CTRL 1 #define KVM_ARM_VCPU_TIMER_IRQ_VTIMER 0 #define KVM_ARM_VCPU_TIMER_IRQ_PTIMER 1 +#define KVM_ARM_VCPU_PVTIME_CTRL 2 +#define KVM_ARM_VCPU_PVTIME_IPA 0 /* KVM_IRQ_LINE irq field index values */ +#define KVM_ARM_IRQ_VCPU2_SHIFT 28 +#define KVM_ARM_IRQ_VCPU2_MASK 0xf #define KVM_ARM_IRQ_TYPE_SHIFT 24 -#define KVM_ARM_IRQ_TYPE_MASK 0xff +#define KVM_ARM_IRQ_TYPE_MASK 0xf #define KVM_ARM_IRQ_VCPU_SHIFT 16 #define KVM_ARM_IRQ_VCPU_MASK 0xff #define KVM_ARM_IRQ_NUM_SHIFT 0 diff --git a/include/linux/kvm.h b/include/linux/kvm.h index 5e3f12d..322b4b5 100644 --- a/include/linux/kvm.h +++ b/include/linux/kvm.h @@ -8,6 +8,7 @@ * Note: you must update KVM_API_VERSION if you change this interface. */ +#include #include #include #include @@ -116,7 +117,7 @@ struct kvm_irq_level { * ACPI gsi notion of irq. * For IA-64 (APIC model) IOAPIC0: irq 0-23; IOAPIC1: irq 24-47.. * For X86 (standard AT mode) PIC0/1: irq 0-15. IOAPIC0: 0-23.. - * For ARM: See Documentation/virt/kvm/api.txt + * For ARM: See Documentation/virt/kvm/api.rst */ union { __u32 irq; @@ -188,10 +189,13 @@ struct kvm_s390_cmma_log { struct kvm_hyperv_exit { #define KVM_EXIT_HYPERV_SYNIC 1 #define KVM_EXIT_HYPERV_HCALL 2 +#define KVM_EXIT_HYPERV_SYNDBG 3 __u32 type; + __u32 pad1; union { struct { __u32 msr; + __u32 pad2; __u64 control; __u64 evt_page; __u64 msg_page; @@ -201,6 +205,29 @@ struct kvm_hyperv_exit { __u64 result; __u64 params[2]; } hcall; + struct { + __u32 msr; + __u32 pad2; + __u64 control; + __u64 status; + __u64 send_page; + __u64 recv_page; + __u64 pending_page; + } syndbg; + } u; +}; + +struct kvm_xen_exit { +#define KVM_EXIT_XEN_HCALL 1 + __u32 type; + union { + struct { + __u32 longmode; + __u32 cpl; + __u64 input; + __u64 result; + __u64 params[6]; + } hcall; } u; }; @@ -235,6 +262,14 @@ struct kvm_hyperv_exit { #define KVM_EXIT_S390_STSI 25 #define KVM_EXIT_IOAPIC_EOI 26 #define KVM_EXIT_HYPERV 27 +#define KVM_EXIT_ARM_NISV 28 +#define KVM_EXIT_X86_RDMSR 29 +#define KVM_EXIT_X86_WRMSR 30 +#define KVM_EXIT_DIRTY_RING_FULL 31 +#define KVM_EXIT_AP_RESET_HOLD 32 +#define KVM_EXIT_X86_BUS_LOCK 33 +#define KVM_EXIT_XEN 34 +#define KVM_EXIT_RISCV_SBI 35 /* For KVM_EXIT_INTERNAL_ERROR */ /* Emulate instruction failed. */ @@ -243,6 +278,11 @@ struct kvm_hyperv_exit { #define KVM_INTERNAL_ERROR_SIMUL_EX 2 /* Encounter unexpected vm-exit due to delivery event. */ #define KVM_INTERNAL_ERROR_DELIVERY_EV 3 +/* Encounter unexpected vm-exit reason */ +#define KVM_INTERNAL_ERROR_UNEXPECTED_EXIT_REASON 4 + +/* Flags that describe what fields in emulation_failure hold valid data. */ +#define KVM_INTERNAL_ERROR_EMULATION_FLAG_INSTRUCTION_BYTES (1ULL << 0) /* for KVM_RUN, returned by mmap(vcpu_fd, offset=0) */ struct kvm_run { @@ -274,6 +314,7 @@ struct kvm_run { /* KVM_EXIT_FAIL_ENTRY */ struct { __u64 hardware_entry_failure_reason; + __u32 cpu; } fail_entry; /* KVM_EXIT_EXCEPTION */ struct { @@ -346,6 +387,25 @@ struct kvm_run { __u32 ndata; __u64 data[16]; } internal; + /* + * KVM_INTERNAL_ERROR_EMULATION + * + * "struct emulation_failure" is an overlay of "struct internal" + * that is used for the KVM_INTERNAL_ERROR_EMULATION sub-type of + * KVM_EXIT_INTERNAL_ERROR. Note, unlike other internal error + * sub-types, this struct is ABI! It also needs to be backwards + * compatible with "struct internal". Take special care that + * "ndata" is correct, that new fields are enumerated in "flags", + * and that each flag enumerates fields that are 64-bit aligned + * and sized (so that ndata+internal.data[] is valid/accurate). + */ + struct { + __u32 suberror; + __u32 ndata; + __u64 flags; + __u8 insn_size; + __u8 insn_bytes[15]; + } emulation_failure; /* KVM_EXIT_OSI */ struct { __u64 gprs[32]; @@ -392,6 +452,31 @@ struct kvm_run { } eoi; /* KVM_EXIT_HYPERV */ struct kvm_hyperv_exit hyperv; + /* KVM_EXIT_ARM_NISV */ + struct { + __u64 esr_iss; + __u64 fault_ipa; + } arm_nisv; + /* KVM_EXIT_X86_RDMSR / KVM_EXIT_X86_WRMSR */ + struct { + __u8 error; /* user -> kernel */ + __u8 pad[7]; +#define KVM_MSR_EXIT_REASON_INVAL (1 << 0) +#define KVM_MSR_EXIT_REASON_UNKNOWN (1 << 1) +#define KVM_MSR_EXIT_REASON_FILTER (1 << 2) + __u32 reason; /* kernel -> user */ + __u32 index; /* kernel -> user */ + __u64 data; /* kernel <-> user */ + } msr; + /* KVM_EXIT_XEN */ + struct kvm_xen_exit xen; + /* KVM_EXIT_RISCV_SBI */ + struct { + unsigned long extension_id; + unsigned long function_id; + unsigned long args[6]; + unsigned long ret[2]; + } riscv_sbi; /* Fix the size of the union. */ char padding[256]; }; @@ -466,12 +551,17 @@ struct kvm_s390_mem_op { __u32 size; /* amount of bytes */ __u32 op; /* type of operation */ __u64 buf; /* buffer in userspace */ - __u8 ar; /* the access register number */ - __u8 reserved[31]; /* should be set to 0 */ + union { + __u8 ar; /* the access register number */ + __u32 sida_offset; /* offset into the sida */ + __u8 reserved[32]; /* should be set to 0 */ + }; }; /* types for kvm_s390_mem_op->op */ #define KVM_S390_MEMOP_LOGICAL_READ 0 #define KVM_S390_MEMOP_LOGICAL_WRITE 1 +#define KVM_S390_MEMOP_SIDA_READ 2 +#define KVM_S390_MEMOP_SIDA_WRITE 3 /* flags for kvm_s390_mem_op->flags */ #define KVM_S390_MEMOP_F_CHECK_ONLY (1ULL << 0) #define KVM_S390_MEMOP_F_INJECT_EXCEPTION (1ULL << 1) @@ -533,6 +623,7 @@ struct kvm_vapic_addr { #define KVM_MP_STATE_CHECK_STOP 6 #define KVM_MP_STATE_OPERATING 7 #define KVM_MP_STATE_LOAD 8 +#define KVM_MP_STATE_AP_RESET_HOLD 9 struct kvm_mp_state { __u32 mp_state; @@ -764,9 +855,10 @@ struct kvm_ppc_resize_hpt { #define KVM_VM_PPC_HV 1 #define KVM_VM_PPC_PR 2 -/* on MIPS, 0 forces trap & emulate, 1 forces VZ ASE */ -#define KVM_VM_MIPS_TE 0 +/* on MIPS, 0 indicates auto, 1 forces VZ ASE, 2 forces trap & emulate */ +#define KVM_VM_MIPS_AUTO 0 #define KVM_VM_MIPS_VZ 1 +#define KVM_VM_MIPS_TE 2 #define KVM_S390_SIE_PAGE_OFFSET 1 @@ -996,6 +1088,38 @@ struct kvm_ppc_resize_hpt { #define KVM_CAP_ARM_PTRAUTH_ADDRESS 171 #define KVM_CAP_ARM_PTRAUTH_GENERIC 172 #define KVM_CAP_PMU_EVENT_FILTER 173 +#define KVM_CAP_ARM_IRQ_LINE_LAYOUT_2 174 +#define KVM_CAP_HYPERV_DIRECT_TLBFLUSH 175 +#define KVM_CAP_PPC_GUEST_DEBUG_SSTEP 176 +#define KVM_CAP_ARM_NISV_TO_USER 177 +#define KVM_CAP_ARM_INJECT_EXT_DABT 178 +#define KVM_CAP_S390_VCPU_RESETS 179 +#define KVM_CAP_S390_PROTECTED 180 +#define KVM_CAP_PPC_SECURE_GUEST 181 +#define KVM_CAP_HALT_POLL 182 +#define KVM_CAP_ASYNC_PF_INT 183 +#define KVM_CAP_LAST_CPU 184 +#define KVM_CAP_SMALLER_MAXPHYADDR 185 +#define KVM_CAP_S390_DIAG318 186 +#define KVM_CAP_STEAL_TIME 187 +#define KVM_CAP_X86_USER_SPACE_MSR 188 +#define KVM_CAP_X86_MSR_FILTER 189 +#define KVM_CAP_ENFORCE_PV_FEATURE_CPUID 190 +#define KVM_CAP_SYS_HYPERV_CPUID 191 +#define KVM_CAP_DIRTY_LOG_RING 192 +#define KVM_CAP_X86_BUS_LOCK_EXIT 193 +#define KVM_CAP_PPC_DAWR1 194 +#define KVM_CAP_SET_GUEST_DEBUG2 195 +#define KVM_CAP_SGX_ATTRIBUTE 196 +#define KVM_CAP_VM_COPY_ENC_CONTEXT_FROM 197 +#define KVM_CAP_PTP_KVM 198 +#define KVM_CAP_HYPERV_ENFORCE_CPUID 199 +#define KVM_CAP_SREGS2 200 +#define KVM_CAP_EXIT_HYPERCALL 201 +#define KVM_CAP_PPC_RPT_INVALIDATE 202 +#define KVM_CAP_BINARY_STATS_FD 203 +#define KVM_CAP_EXIT_ON_EMULATION_FAILURE 204 +#define KVM_CAP_ARM_MTE 205 #ifdef KVM_CAP_IRQ_ROUTING @@ -1069,6 +1193,11 @@ struct kvm_x86_mce { #endif #ifdef KVM_CAP_XEN_HVM +#define KVM_XEN_HVM_CONFIG_HYPERCALL_MSR (1 << 0) +#define KVM_XEN_HVM_CONFIG_INTERCEPT_HCALL (1 << 1) +#define KVM_XEN_HVM_CONFIG_SHARED_INFO (1 << 2) +#define KVM_XEN_HVM_CONFIG_RUNSTATE (1 << 3) + struct kvm_xen_hvm_config { __u32 flags; __u32 msr; @@ -1086,7 +1215,7 @@ struct kvm_xen_hvm_config { * * KVM_IRQFD_FLAG_RESAMPLE indicates resamplefd is valid and specifies * the irqfd to operate in resampling mode for level triggered interrupt - * emulation. See Documentation/virt/kvm/api.txt. + * emulation. See Documentation/virt/kvm/api.rst. */ #define KVM_IRQFD_FLAG_RESAMPLE (1 << 1) @@ -1142,6 +1271,7 @@ struct kvm_dirty_tlb { #define KVM_REG_S390 0x5000000000000000ULL #define KVM_REG_ARM64 0x6000000000000000ULL #define KVM_REG_MIPS 0x7000000000000000ULL +#define KVM_REG_RISCV 0x8000000000000000ULL #define KVM_REG_SIZE_SHIFT 52 #define KVM_REG_SIZE_MASK 0x00f0000000000000ULL @@ -1222,6 +1352,8 @@ enum kvm_device_type { #define KVM_DEV_TYPE_ARM_VGIC_ITS KVM_DEV_TYPE_ARM_VGIC_ITS KVM_DEV_TYPE_XIVE, #define KVM_DEV_TYPE_XIVE KVM_DEV_TYPE_XIVE + KVM_DEV_TYPE_ARM_PV_TIME, +#define KVM_DEV_TYPE_ARM_PV_TIME KVM_DEV_TYPE_ARM_PV_TIME KVM_DEV_TYPE_MAX, }; @@ -1332,6 +1464,8 @@ struct kvm_s390_ucas_mapping { #define KVM_PPC_GET_CPU_CHAR _IOR(KVMIO, 0xb1, struct kvm_ppc_cpu_char) /* Available with KVM_CAP_PMU_EVENT_FILTER */ #define KVM_SET_PMU_EVENT_FILTER _IOW(KVMIO, 0xb2, struct kvm_pmu_event_filter) +#define KVM_PPC_SVM_OFF _IO(KVMIO, 0xb3) +#define KVM_ARM_MTE_COPY_TAGS _IOR(KVMIO, 0xb4, struct kvm_arm_copy_mte_tags) /* ioctl for vm fd */ #define KVM_CREATE_DEVICE _IOWR(KVMIO, 0xe0, struct kvm_create_device) @@ -1450,12 +1584,109 @@ struct kvm_enc_region { /* Available with KVM_CAP_MANUAL_DIRTY_LOG_PROTECT_2 */ #define KVM_CLEAR_DIRTY_LOG _IOWR(KVMIO, 0xc0, struct kvm_clear_dirty_log) -/* Available with KVM_CAP_HYPERV_CPUID */ +/* Available with KVM_CAP_HYPERV_CPUID (vcpu) / KVM_CAP_SYS_HYPERV_CPUID (system) */ #define KVM_GET_SUPPORTED_HV_CPUID _IOWR(KVMIO, 0xc1, struct kvm_cpuid2) /* Available with KVM_CAP_ARM_SVE */ #define KVM_ARM_VCPU_FINALIZE _IOW(KVMIO, 0xc2, int) +/* Available with KVM_CAP_S390_VCPU_RESETS */ +#define KVM_S390_NORMAL_RESET _IO(KVMIO, 0xc3) +#define KVM_S390_CLEAR_RESET _IO(KVMIO, 0xc4) + +struct kvm_s390_pv_sec_parm { + __u64 origin; + __u64 length; +}; + +struct kvm_s390_pv_unp { + __u64 addr; + __u64 size; + __u64 tweak; +}; + +enum pv_cmd_id { + KVM_PV_ENABLE, + KVM_PV_DISABLE, + KVM_PV_SET_SEC_PARMS, + KVM_PV_UNPACK, + KVM_PV_VERIFY, + KVM_PV_PREP_RESET, + KVM_PV_UNSHARE_ALL, +}; + +struct kvm_pv_cmd { + __u32 cmd; /* Command to be executed */ + __u16 rc; /* Ultravisor return code */ + __u16 rrc; /* Ultravisor return reason code */ + __u64 data; /* Data or address */ + __u32 flags; /* flags for future extensions. Must be 0 for now */ + __u32 reserved[3]; +}; + +/* Available with KVM_CAP_S390_PROTECTED */ +#define KVM_S390_PV_COMMAND _IOWR(KVMIO, 0xc5, struct kvm_pv_cmd) + +/* Available with KVM_CAP_X86_MSR_FILTER */ +#define KVM_X86_SET_MSR_FILTER _IOW(KVMIO, 0xc6, struct kvm_msr_filter) + +/* Available with KVM_CAP_DIRTY_LOG_RING */ +#define KVM_RESET_DIRTY_RINGS _IO(KVMIO, 0xc7) + +/* Per-VM Xen attributes */ +#define KVM_XEN_HVM_GET_ATTR _IOWR(KVMIO, 0xc8, struct kvm_xen_hvm_attr) +#define KVM_XEN_HVM_SET_ATTR _IOW(KVMIO, 0xc9, struct kvm_xen_hvm_attr) + +struct kvm_xen_hvm_attr { + __u16 type; + __u16 pad[3]; + union { + __u8 long_mode; + __u8 vector; + struct { + __u64 gfn; + } shared_info; + __u64 pad[8]; + } u; +}; + +/* Available with KVM_CAP_XEN_HVM / KVM_XEN_HVM_CONFIG_SHARED_INFO */ +#define KVM_XEN_ATTR_TYPE_LONG_MODE 0x0 +#define KVM_XEN_ATTR_TYPE_SHARED_INFO 0x1 +#define KVM_XEN_ATTR_TYPE_UPCALL_VECTOR 0x2 + +/* Per-vCPU Xen attributes */ +#define KVM_XEN_VCPU_GET_ATTR _IOWR(KVMIO, 0xca, struct kvm_xen_vcpu_attr) +#define KVM_XEN_VCPU_SET_ATTR _IOW(KVMIO, 0xcb, struct kvm_xen_vcpu_attr) + +#define KVM_GET_SREGS2 _IOR(KVMIO, 0xcc, struct kvm_sregs2) +#define KVM_SET_SREGS2 _IOW(KVMIO, 0xcd, struct kvm_sregs2) + +struct kvm_xen_vcpu_attr { + __u16 type; + __u16 pad[3]; + union { + __u64 gpa; + __u64 pad[8]; + struct { + __u64 state; + __u64 state_entry_time; + __u64 time_running; + __u64 time_runnable; + __u64 time_blocked; + __u64 time_offline; + } runstate; + } u; +}; + +/* Available with KVM_CAP_XEN_HVM / KVM_XEN_HVM_CONFIG_SHARED_INFO */ +#define KVM_XEN_VCPU_ATTR_TYPE_VCPU_INFO 0x0 +#define KVM_XEN_VCPU_ATTR_TYPE_VCPU_TIME_INFO 0x1 +#define KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_ADDR 0x2 +#define KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_CURRENT 0x3 +#define KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_DATA 0x4 +#define KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_ADJUST 0x5 + /* Secure Encrypted Virtualization command */ enum sev_cmd_id { /* Guest initialization commands */ @@ -1484,6 +1715,10 @@ enum sev_cmd_id { KVM_SEV_DBG_ENCRYPT, /* Guest certificates commands */ KVM_SEV_CERT_EXPORT, + /* Attestation report */ + KVM_SEV_GET_ATTESTATION_REPORT, + /* Guest Migration Extension */ + KVM_SEV_SEND_CANCEL, KVM_SEV_NR_MAX, }; @@ -1536,6 +1771,51 @@ struct kvm_sev_dbg { __u32 len; }; +struct kvm_sev_attestation_report { + __u8 mnonce[16]; + __u64 uaddr; + __u32 len; +}; + +struct kvm_sev_send_start { + __u32 policy; + __u64 pdh_cert_uaddr; + __u32 pdh_cert_len; + __u64 plat_certs_uaddr; + __u32 plat_certs_len; + __u64 amd_certs_uaddr; + __u32 amd_certs_len; + __u64 session_uaddr; + __u32 session_len; +}; + +struct kvm_sev_send_update_data { + __u64 hdr_uaddr; + __u32 hdr_len; + __u64 guest_uaddr; + __u32 guest_len; + __u64 trans_uaddr; + __u32 trans_len; +}; + +struct kvm_sev_receive_start { + __u32 handle; + __u32 policy; + __u64 pdh_uaddr; + __u32 pdh_len; + __u64 session_uaddr; + __u32 session_len; +}; + +struct kvm_sev_receive_update_data { + __u64 hdr_uaddr; + __u32 hdr_len; + __u64 guest_uaddr; + __u32 guest_len; + __u64 trans_uaddr; + __u32 trans_len; +}; + #define KVM_DEV_ASSIGN_ENABLE_IOMMU (1 << 0) #define KVM_DEV_ASSIGN_PCI_2_3 (1 << 1) #define KVM_DEV_ASSIGN_MASK_INTX (1 << 2) @@ -1606,4 +1886,133 @@ struct kvm_hyperv_eventfd { #define KVM_HYPERV_CONN_ID_MASK 0x00ffffff #define KVM_HYPERV_EVENTFD_DEASSIGN (1 << 0) +#define KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE (1 << 0) +#define KVM_DIRTY_LOG_INITIALLY_SET (1 << 1) + +/* + * Arch needs to define the macro after implementing the dirty ring + * feature. KVM_DIRTY_LOG_PAGE_OFFSET should be defined as the + * starting page offset of the dirty ring structures. + */ +#ifndef KVM_DIRTY_LOG_PAGE_OFFSET +#define KVM_DIRTY_LOG_PAGE_OFFSET 0 +#endif + +/* + * KVM dirty GFN flags, defined as: + * + * |---------------+---------------+--------------| + * | bit 1 (reset) | bit 0 (dirty) | Status | + * |---------------+---------------+--------------| + * | 0 | 0 | Invalid GFN | + * | 0 | 1 | Dirty GFN | + * | 1 | X | GFN to reset | + * |---------------+---------------+--------------| + * + * Lifecycle of a dirty GFN goes like: + * + * dirtied harvested reset + * 00 -----------> 01 -------------> 1X -------+ + * ^ | + * | | + * +------------------------------------------+ + * + * The userspace program is only responsible for the 01->1X state + * conversion after harvesting an entry. Also, it must not skip any + * dirty bits, so that dirty bits are always harvested in sequence. + */ +#define KVM_DIRTY_GFN_F_DIRTY _BITUL(0) +#define KVM_DIRTY_GFN_F_RESET _BITUL(1) +#define KVM_DIRTY_GFN_F_MASK 0x3 + +/* + * KVM dirty rings should be mapped at KVM_DIRTY_LOG_PAGE_OFFSET of + * per-vcpu mmaped regions as an array of struct kvm_dirty_gfn. The + * size of the gfn buffer is decided by the first argument when + * enabling KVM_CAP_DIRTY_LOG_RING. + */ +struct kvm_dirty_gfn { + __u32 flags; + __u32 slot; + __u64 offset; +}; + +#define KVM_BUS_LOCK_DETECTION_OFF (1 << 0) +#define KVM_BUS_LOCK_DETECTION_EXIT (1 << 1) + +/** + * struct kvm_stats_header - Header of per vm/vcpu binary statistics data. + * @flags: Some extra information for header, always 0 for now. + * @name_size: The size in bytes of the memory which contains statistics + * name string including trailing '\0'. The memory is allocated + * at the send of statistics descriptor. + * @num_desc: The number of statistics the vm or vcpu has. + * @id_offset: The offset of the vm/vcpu stats' id string in the file pointed + * by vm/vcpu stats fd. + * @desc_offset: The offset of the vm/vcpu stats' descriptor block in the file + * pointd by vm/vcpu stats fd. + * @data_offset: The offset of the vm/vcpu stats' data block in the file + * pointed by vm/vcpu stats fd. + * + * This is the header userspace needs to read from stats fd before any other + * readings. It is used by userspace to discover all the information about the + * vm/vcpu's binary statistics. + * Userspace reads this header from the start of the vm/vcpu's stats fd. + */ +struct kvm_stats_header { + __u32 flags; + __u32 name_size; + __u32 num_desc; + __u32 id_offset; + __u32 desc_offset; + __u32 data_offset; +}; + +#define KVM_STATS_TYPE_SHIFT 0 +#define KVM_STATS_TYPE_MASK (0xF << KVM_STATS_TYPE_SHIFT) +#define KVM_STATS_TYPE_CUMULATIVE (0x0 << KVM_STATS_TYPE_SHIFT) +#define KVM_STATS_TYPE_INSTANT (0x1 << KVM_STATS_TYPE_SHIFT) +#define KVM_STATS_TYPE_PEAK (0x2 << KVM_STATS_TYPE_SHIFT) +#define KVM_STATS_TYPE_LINEAR_HIST (0x3 << KVM_STATS_TYPE_SHIFT) +#define KVM_STATS_TYPE_LOG_HIST (0x4 << KVM_STATS_TYPE_SHIFT) +#define KVM_STATS_TYPE_MAX KVM_STATS_TYPE_LOG_HIST + +#define KVM_STATS_UNIT_SHIFT 4 +#define KVM_STATS_UNIT_MASK (0xF << KVM_STATS_UNIT_SHIFT) +#define KVM_STATS_UNIT_NONE (0x0 << KVM_STATS_UNIT_SHIFT) +#define KVM_STATS_UNIT_BYTES (0x1 << KVM_STATS_UNIT_SHIFT) +#define KVM_STATS_UNIT_SECONDS (0x2 << KVM_STATS_UNIT_SHIFT) +#define KVM_STATS_UNIT_CYCLES (0x3 << KVM_STATS_UNIT_SHIFT) +#define KVM_STATS_UNIT_MAX KVM_STATS_UNIT_CYCLES + +#define KVM_STATS_BASE_SHIFT 8 +#define KVM_STATS_BASE_MASK (0xF << KVM_STATS_BASE_SHIFT) +#define KVM_STATS_BASE_POW10 (0x0 << KVM_STATS_BASE_SHIFT) +#define KVM_STATS_BASE_POW2 (0x1 << KVM_STATS_BASE_SHIFT) +#define KVM_STATS_BASE_MAX KVM_STATS_BASE_POW2 + +/** + * struct kvm_stats_desc - Descriptor of a KVM statistics. + * @flags: Annotations of the stats, like type, unit, etc. + * @exponent: Used together with @flags to determine the unit. + * @size: The number of data items for this stats. + * Every data item is of type __u64. + * @offset: The offset of the stats to the start of stat structure in + * structure kvm or kvm_vcpu. + * @bucket_size: A parameter value used for histogram stats. It is only used + * for linear histogram stats, specifying the size of the bucket; + * @name: The name string for the stats. Its size is indicated by the + * &kvm_stats_header->name_size. + */ +struct kvm_stats_desc { + __u32 flags; + __s16 exponent; + __u16 size; + __u32 offset; + __u32 bucket_size; + char name[]; +}; + +#define KVM_GET_STATS_FD _IO(KVMIO, 0xce) + #endif /* __LINUX_KVM_H */ diff --git a/powerpc/include/asm/kvm.h b/powerpc/include/asm/kvm.h index b0f72de..9f18fa0 100644 --- a/powerpc/include/asm/kvm.h +++ b/powerpc/include/asm/kvm.h @@ -640,6 +640,13 @@ struct kvm_ppc_cpu_char { #define KVM_REG_PPC_ONLINE (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xbf) #define KVM_REG_PPC_PTCR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xc0) +/* POWER10 registers */ +#define KVM_REG_PPC_MMCR3 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xc1) +#define KVM_REG_PPC_SIER2 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xc2) +#define KVM_REG_PPC_SIER3 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xc3) +#define KVM_REG_PPC_DAWR1 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xc4) +#define KVM_REG_PPC_DAWRX1 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xc5) + /* Transactional Memory checkpointed state: * This is all GPRs, all VSX regs and a subset of SPRs */ @@ -667,6 +674,8 @@ struct kvm_ppc_cpu_char { /* PPC64 eXternal Interrupt Controller Specification */ #define KVM_DEV_XICS_GRP_SOURCES 1 /* 64-bit source attributes */ +#define KVM_DEV_XICS_GRP_CTRL 2 +#define KVM_DEV_XICS_NR_SERVERS 1 /* Layout of 64-bit source attribute values */ #define KVM_XICS_DESTINATION_SHIFT 0 @@ -683,6 +692,7 @@ struct kvm_ppc_cpu_char { #define KVM_DEV_XIVE_GRP_CTRL 1 #define KVM_DEV_XIVE_RESET 1 #define KVM_DEV_XIVE_EQ_SYNC 2 +#define KVM_DEV_XIVE_NR_SERVERS 3 #define KVM_DEV_XIVE_GRP_SOURCE 2 /* 64-bit source identifier */ #define KVM_DEV_XIVE_GRP_SOURCE_CONFIG 3 /* 64-bit source identifier */ #define KVM_DEV_XIVE_GRP_EQ_CONFIG 4 /* 64-bit EQ identifier */ diff --git a/x86/include/asm/kvm.h b/x86/include/asm/kvm.h index 503d3f4..2ef1f65 100644 --- a/x86/include/asm/kvm.h +++ b/x86/include/asm/kvm.h @@ -12,6 +12,7 @@ #define KVM_PIO_PAGE_OFFSET 1 #define KVM_COALESCED_MMIO_PAGE_OFFSET 2 +#define KVM_DIRTY_LOG_PAGE_OFFSET 64 #define DE_VECTOR 0 #define DB_VECTOR 1 @@ -111,6 +112,7 @@ struct kvm_ioapic_state { #define KVM_NR_IRQCHIPS 3 #define KVM_RUN_X86_SMM (1 << 0) +#define KVM_RUN_X86_BUS_LOCK (1 << 1) /* for KVM_GET_REGS and KVM_SET_REGS */ struct kvm_regs { @@ -157,6 +159,19 @@ struct kvm_sregs { __u64 interrupt_bitmap[(KVM_NR_INTERRUPTS + 63) / 64]; }; +struct kvm_sregs2 { + /* out (KVM_GET_SREGS2) / in (KVM_SET_SREGS2) */ + struct kvm_segment cs, ds, es, fs, gs, ss; + struct kvm_segment tr, ldt; + struct kvm_dtable gdt, idt; + __u64 cr0, cr2, cr3, cr4, cr8; + __u64 efer; + __u64 apic_base; + __u64 flags; + __u64 pdptrs[4]; +}; +#define KVM_SREGS2_FLAGS_PDPTRS_VALID 1 + /* for KVM_GET_FPU and KVM_SET_FPU */ struct kvm_fpu { __u8 fpr[8][16]; @@ -192,6 +207,26 @@ struct kvm_msr_list { __u32 indices[0]; }; +/* Maximum size of any access bitmap in bytes */ +#define KVM_MSR_FILTER_MAX_BITMAP_SIZE 0x600 + +/* for KVM_X86_SET_MSR_FILTER */ +struct kvm_msr_filter_range { +#define KVM_MSR_FILTER_READ (1 << 0) +#define KVM_MSR_FILTER_WRITE (1 << 1) + __u32 flags; + __u32 nmsrs; /* number of msrs in bitmap */ + __u32 base; /* MSR index the bitmap starts at */ + __u8 *bitmap; /* a 1 bit allows the operations in flags, 0 denies */ +}; + +#define KVM_MSR_FILTER_MAX_RANGES 16 +struct kvm_msr_filter { +#define KVM_MSR_FILTER_DEFAULT_ALLOW (0 << 0) +#define KVM_MSR_FILTER_DEFAULT_DENY (1 << 0) + __u32 flags; + struct kvm_msr_filter_range ranges[KVM_MSR_FILTER_MAX_RANGES]; +}; struct kvm_cpuid_entry { __u32 function; @@ -260,6 +295,7 @@ struct kvm_debug_exit_arch { #define KVM_GUESTDBG_USE_HW_BP 0x00020000 #define KVM_GUESTDBG_INJECT_DB 0x00040000 #define KVM_GUESTDBG_INJECT_BP 0x00080000 +#define KVM_GUESTDBG_BLOCKIRQ 0x00100000 /* for KVM_SET_GUEST_DEBUG */ struct kvm_guest_debug_arch { @@ -385,17 +421,23 @@ struct kvm_sync_regs { #define KVM_X86_QUIRK_MISC_ENABLE_NO_MWAIT (1 << 4) #define KVM_STATE_NESTED_FORMAT_VMX 0 -#define KVM_STATE_NESTED_FORMAT_SVM 1 /* unused */ +#define KVM_STATE_NESTED_FORMAT_SVM 1 #define KVM_STATE_NESTED_GUEST_MODE 0x00000001 #define KVM_STATE_NESTED_RUN_PENDING 0x00000002 #define KVM_STATE_NESTED_EVMCS 0x00000004 +#define KVM_STATE_NESTED_MTF_PENDING 0x00000008 +#define KVM_STATE_NESTED_GIF_SET 0x00000100 #define KVM_STATE_NESTED_SMM_GUEST_MODE 0x00000001 #define KVM_STATE_NESTED_SMM_VMXON 0x00000002 #define KVM_STATE_NESTED_VMX_VMCS_SIZE 0x1000 +#define KVM_STATE_NESTED_SVM_VMCB_SIZE 0x1000 + +#define KVM_STATE_VMX_PREEMPTION_TIMER_DEADLINE 0x00000001 + struct kvm_vmx_nested_state_data { __u8 vmcs12[KVM_STATE_NESTED_VMX_VMCS_SIZE]; __u8 shadow_vmcs12[KVM_STATE_NESTED_VMX_VMCS_SIZE]; @@ -408,6 +450,20 @@ struct kvm_vmx_nested_state_hdr { struct { __u16 flags; } smm; + + __u16 pad; + + __u32 flags; + __u64 preemption_timer_deadline; +}; + +struct kvm_svm_nested_state_data { + /* Save area only used if KVM_STATE_NESTED_RUN_PENDING. */ + __u8 vmcb12[KVM_STATE_NESTED_SVM_VMCB_SIZE]; +}; + +struct kvm_svm_nested_state_hdr { + __u64 vmcb_pa; }; /* for KVM_CAP_NESTED_STATE */ @@ -418,6 +474,7 @@ struct kvm_nested_state { union { struct kvm_vmx_nested_state_hdr vmx; + struct kvm_svm_nested_state_hdr svm; /* Pad the header to 128 bytes. */ __u8 pad[120]; @@ -430,6 +487,7 @@ struct kvm_nested_state { */ union { struct kvm_vmx_nested_state_data vmx[0]; + struct kvm_svm_nested_state_data svm[0]; } data; }; From patchwork Mon Sep 27 11:42:21 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anup Patel X-Patchwork-Id: 12519633 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A5052C433EF for ; Mon, 27 Sep 2021 11:43:10 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 808A26108E for ; Mon, 27 Sep 2021 11:43:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234306AbhI0Loq (ORCPT ); Mon, 27 Sep 2021 07:44:46 -0400 Received: from esa2.hgst.iphmx.com ([68.232.143.124]:8740 "EHLO esa2.hgst.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234053AbhI0Lob (ORCPT ); Mon, 27 Sep 2021 07:44:31 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=wdc.com; i=@wdc.com; q=dns/txt; s=dkim.wdc.com; t=1632742974; x=1664278974; h=from:to:cc:subject:date:message-id:in-reply-to: references:content-transfer-encoding:mime-version; bh=+z4VyqNMDh68rsrg5YDCrOjN16jgzs4QX071Yspmc7s=; b=DvEVthULt/NwMc9UlZ4CeEAawm7NGYh5qKid5d2MDgMjyZ3SF7V1WWvF y+4/hdV2YVDsX4wAOEoXwnEue2AZYIU9yQumWF6Sfkb321ayDu1v3hcWy BnzDlagQlSJN/cBOZy5pVBJVxWr88mP/LfzaWsbUdfGp2CNTjxIutxQPo 2WeSnRaAkxougO3k+3LnAgaZ7nc89S2EPhtcpXFOBnqF6kr5/CaRi/8N3 GJ1lawfZMxjC5cj0o2e1BoOuKupu6A8KlJBw0wsFiQlfqjSNSp+LWiTWO DtMu9jzIXdZFLHEXyHjkuCl4n/TYBbIrOlZPcyPAUSWbAbHzeTejs6mdO w==; X-IronPort-AV: E=Sophos;i="5.85,326,1624291200"; d="scan'208";a="284861962" Received: from mail-dm6nam10lp2105.outbound.protection.outlook.com (HELO NAM10-DM6-obe.outbound.protection.outlook.com) ([104.47.58.105]) by ob1.hgst.iphmx.com with ESMTP; 27 Sep 2021 19:42:53 +0800 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=AsXbfC9B3T+PI3mOhNNk8sUzmz7EPgy30I/CmRQT5lCkzcJ99ETgvfTiJQP0AdOoXxu79VCD6QsG1rdXVZqEOzRhiG0UQoLCTZcP6HXMZ4hNNc9wfN5TVNnMvZIOz79YzgCzIP5SQ5s5w7YuVNh7hJ7AJlaVTSlP6Uv5UtMtJHSIyBlFaqxkAfANBfySFjJBjKaf7/2JEQNVL8APPh9pXkel4tndI9Cy9U2eBgTMbKetK2FwBXFLTF+Udnq6GwhPsZD/d0gAcNZ0lfa6VmlTlb/7mEItgY7OgLZutXvdj20o1Q6awTV0FBdcajJcFi4RD4MADMtgQggGXRZSoIfL0w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=nYxooHB67uEiqk8rm2bx7Jss/vz5cqsnLFSU757edUU=; b=B4va3kT6NtlMEPpNgkT7Qrp5P9ybPZSvZ8sHXJYKBLlLmgLaLWfsEZ6mJs7xY5sGjXTQeo5e4otBZStz+z8bhSneDajsMupj8Tu9UNYjaRtSWITOlvNfLEhU2sPQ/1ig3/6VaXC5569LH3kiGCJnYun2IrciipqfVpJa9+42sURPWGVIM78Hnl3xIuJtaMIzWIAQwbTJb1PKAtbpPwj1d5w2h32h2dRfcHLOr5IpqmVBrKHB5o+vzwimFYrupGn/anJhzH+5SfYVrHplqQ7ytB+W9+cpFEtY3xaRZo3NCkI4YwjJz6B5wh9RGKoGXwFtvvR9ilmD7lOrJfjQUbU63w== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=wdc.com; dmarc=pass action=none header.from=wdc.com; dkim=pass header.d=wdc.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sharedspace.onmicrosoft.com; s=selector2-sharedspace-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=nYxooHB67uEiqk8rm2bx7Jss/vz5cqsnLFSU757edUU=; b=Hj++PPjVPTgtk1CzUXvdu7oz4NM7PgIUzyO+rb675Xv9At5DmuTzfFp06peBMm/hkNuQFXOA54s5ISh/JuGNWy62Rit24CDWqRIxlVG/QtT0sKhvN11KbNY0tLvI0pd5A7pR/qO5tQnj7Dxzs5vw6s5ovDzejqxV2uNmZn4MDJw= Authentication-Results: kernel.org; dkim=none (message not signed) header.d=none;kernel.org; dmarc=none action=none header.from=wdc.com; Received: from CO6PR04MB7812.namprd04.prod.outlook.com (2603:10b6:303:138::6) by CO1PR04MB8236.namprd04.prod.outlook.com (2603:10b6:303:163::17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4544.14; Mon, 27 Sep 2021 11:42:52 +0000 Received: from CO6PR04MB7812.namprd04.prod.outlook.com ([fe80::6830:650b:8265:af0b]) by CO6PR04MB7812.namprd04.prod.outlook.com ([fe80::6830:650b:8265:af0b%6]) with mapi id 15.20.4544.021; Mon, 27 Sep 2021 11:42:52 +0000 From: Anup Patel To: Will Deacon Cc: Paolo Bonzini , Atish Patra , Alistair Francis , Anup Patel , kvm@vger.kernel.org, kvm-riscv@lists.infradead.org, Anup Patel Subject: [PATCH v9 2/8] riscv: Initial skeletal support Date: Mon, 27 Sep 2021 17:12:21 +0530 Message-Id: <20210927114227.1089403-3-anup.patel@wdc.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210927114227.1089403-1-anup.patel@wdc.com> References: <20210927114227.1089403-1-anup.patel@wdc.com> X-ClientProxiedBy: MA1PR01CA0173.INDPRD01.PROD.OUTLOOK.COM (2603:1096:a01:d::14) To CO6PR04MB7812.namprd04.prod.outlook.com (2603:10b6:303:138::6) MIME-Version: 1.0 Received: from wdc.com (122.179.75.205) by MA1PR01CA0173.INDPRD01.PROD.OUTLOOK.COM (2603:1096:a01:d::14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4544.14 via Frontend Transport; Mon, 27 Sep 2021 11:42:49 +0000 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 6e03d676-6a2d-49be-0908-08d981abf02f X-MS-TrafficTypeDiagnostic: CO1PR04MB8236: X-MS-Exchange-Transport-Forked: True X-Microsoft-Antispam-PRVS: WDCIPOUTBOUND: EOP-TRUE X-MS-Oob-TLC-OOBClassifiers: OLM:416; X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: dd0vwt+P3itCzdcc4ioiY3/dFhs5rXjcbJtWZyCZaQms3j9B+lfF2nTYUSIlaIFU/dvkDD2CLofWovryagtwWDQJReFzioYhQqxwvqy1S5bEvMjJNhvS6bXXQ4i+atqpO8fgTpVzfgo/n9LZ+dkcOA4bvj+ytBzqlMZntH41544InFqyTmil+Ssu/0/fC9f/h7oZOtZTwdF/PGZt3QJrYfDeRRhZkb+YfX5o9l9KjGXH2UEt3apXs0f/Cp6lkeAjlZWSrFvoZxIXY5YeegPcu4wOKJpHOCiEE5haMWg3NXhJfXFIywrFfxy9622dkCFpFgVqA8bwQ9Ah02zLxnbYARtMrgBshfG69aMOMSGBB0xCt9SA2hKNIYQyOIHL2z/88pj35frRMnHt7C1UZQrYEjj2Fc1VMw6/bj2o7X5l1lJdRwY/hRLV47yI/2AdDaaTxgWIvCoqlL6rjk4gkxhsuL3sRB6XX5gMWj6FSHZiOpXFJtx1RCKHvkcfJiLMGqi8PW+FSAFMkZn+X1k256QA2sfB4wjsw6m4NxUA1xn5ekVEHOrSNgNLH7JxquJ5lrq8d7tLoQJlOSfRZVyLjRH93Wvzmrs7h39EyypdtPiJlkgaWUkSLpu9c46iTnGeNnw+2QpMIqJhdyrwn4dPDo5RIhF0LCCKcmnHIWFdIeX2xT2z7q3uge4itoDcon75sD4v X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:CO6PR04MB7812.namprd04.prod.outlook.com;PTR:;CAT:NONE;SFS:(4636009)(366004)(6916009)(316002)(66946007)(44832011)(38100700002)(54906003)(186003)(55016002)(38350700002)(8936002)(508600001)(7696005)(6666004)(1076003)(36756003)(66476007)(66556008)(4326008)(2616005)(5660300002)(86362001)(2906002)(8676002)(8886007)(52116002)(26005)(83380400001)(30864003)(956004);DIR:OUT;SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: g6F+1E13rP0uCN4rmtR75SnqFBBdjJX4Ud5BPcy7HQlTDegQp0fpa9Qp9pJWe+kyLf8fUf6VBFRUECaRBUXCjSNAPSPJuEWHI/LGgFt857ZlXjy3Gl5SMZeh24/HANbia3qQrLYrcjZpuqqFDgGklxjnZqk4lzwB7a2vGHYI6kJ5OORIVU+EvlHVsd0JBvkkAyAAhbz7leUU9MSqyNRZMbA+ex439OK+hKjCj/jt1AtcGdgTBG3WiTKZmVVbPCG0XCf2DVh1Iuqagdbl2EBLUGKi9gggssY/2Pq8GripjjjO26nYicQNxebo7Mz1HJtiDuHMzMoXdi8e0BJGmZ2pVUgA7ALOhBidMIwLHJI65zNT6idF4G4Rl2t5s49UQe9dE31wyk5OJQQ74DCq2r4sZS0LwSOU1v59jpib9EdeESBn6si4B9OzQFEjlZbMu0u4N5vBXXzpibovwpLcol0DrSAgn8U2QHd0R+bqCQ7EH32RQCCJWQdyNCV3Ifp+p7Kf3DW+l37aJ1M8sfn7x//t5HM0g4qLF0vJNnT+8FhjcJJt+qnllPaU/ISGAN4ZBIVwYt4e5usqkIb7EuxVj9GYXdmQ2li+CIQeSnj/VG8QyddVkm3bu35Qyc45iIJ45A+AjJcvrca0b5GPObxf6Dj6EcHN6lXP1xjrYjEoHu/CazL5vQM6EO2tv/HW2SBXkIP9KpN6Ik0yGV/g4ySG1OjyiEzKTxvxM931/c6u//vClT6CtLG9Vh1bTQJVx/wdoFlLk9+obMCLuJOgfj7h0MAi9jXiYRPPCxx5P5cSvAPSJtaDMYZzDPZNNK1R9mBmponhEv6ASFbMiYosnXUO2GXgeRKU+gChYQ0nP8XN+2IN2gXipCsv5dP+2Z7KbaqIxnD6S1w3gzRg+VwvwgCiLejWUb87Nt6mP6cm42bBQ+Aepm+pb1XmC45hoPz07qMntqX3RX35ngT1ylwbxxbHCNVXcRFfiWwWQ/S8VkaqiwjPfi/vwzWbMTDr3wTZ2AUd/kqkNsTtKPM0Hnm00Mm24Q0+JTbFVMNY3qMATXYnKdBD6z0U4ZHCmOUL1JVSaMn7xkqTOY9PWW1rqfTP3Ochcg2MkimoCAFUk61isGbsKKwrZ8lF2+jjUopuM8BZCFGgCYdyPsaciWo6/+VpDb82eodM7bKZKdA+GKs3qcFIe8+3KlZWfqbAQYMlisr45k10Z1ijbwawd0Sn5gXq0IYyewHuZTJG26d6UySEshth+vr4f98wXrkW5o6jvhaGfbw6+Vb8c9qBmLg0EOdkIbgu9ZdOZQNjCX1XyLBWBcndkEfGHbUJChCzq8tliytGlhS6FwEx X-OriginatorOrg: wdc.com X-MS-Exchange-CrossTenant-Network-Message-Id: 6e03d676-6a2d-49be-0908-08d981abf02f X-MS-Exchange-CrossTenant-AuthSource: CO6PR04MB7812.namprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 27 Sep 2021 11:42:52.0014 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: b61c8803-16f3-4c35-9b17-6f65f441df86 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: uhgMXUadDjlOVX+6PZFr+FE8/kJBo4NlWo6DqJINl07zb7rkYHUcIt0p5vBt1Ni9tKLauBIvv1yda+rqqdjilA== X-MS-Exchange-Transport-CrossTenantHeadersStamped: CO1PR04MB8236 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org This patch adds initial skeletal KVMTOOL RISC-V support which just compiles for RV32 and RV64 host. Signed-off-by: Anup Patel --- INSTALL | 7 +- Makefile | 21 ++++- riscv/include/asm/kvm.h | 128 ++++++++++++++++++++++++++++ riscv/include/kvm/barrier.h | 14 +++ riscv/include/kvm/fdt-arch.h | 4 + riscv/include/kvm/kvm-arch.h | 66 ++++++++++++++ riscv/include/kvm/kvm-config-arch.h | 9 ++ riscv/include/kvm/kvm-cpu-arch.h | 47 ++++++++++ riscv/ioport.c | 7 ++ riscv/irq.c | 13 +++ riscv/kvm-cpu.c | 64 ++++++++++++++ riscv/kvm.c | 61 +++++++++++++ util/update_headers.sh | 2 +- 13 files changed, 438 insertions(+), 5 deletions(-) create mode 100644 riscv/include/asm/kvm.h create mode 100644 riscv/include/kvm/barrier.h create mode 100644 riscv/include/kvm/fdt-arch.h create mode 100644 riscv/include/kvm/kvm-arch.h create mode 100644 riscv/include/kvm/kvm-config-arch.h create mode 100644 riscv/include/kvm/kvm-cpu-arch.h create mode 100644 riscv/ioport.c create mode 100644 riscv/irq.c create mode 100644 riscv/kvm-cpu.c create mode 100644 riscv/kvm.c diff --git a/INSTALL b/INSTALL index ca8e022..951b123 100644 --- a/INSTALL +++ b/INSTALL @@ -26,8 +26,8 @@ For Fedora based systems: For OpenSUSE based systems: # zypper install glibc-devel-static -Architectures which require device tree (PowerPC, ARM, ARM64) also require -libfdt. +Architectures which require device tree (PowerPC, ARM, ARM64, RISC-V) also +require libfdt. deb: $ sudo apt-get install libfdt-dev Fedora: # yum install libfdt-devel OpenSUSE: # zypper install libfdt1-devel @@ -64,6 +64,7 @@ to the Linux name of the architecture. Architectures supported: - arm - arm64 - mips +- riscv If ARCH is not provided, the target architecture will be automatically determined by running "uname -m" on your host, resulting in a native build. @@ -81,7 +82,7 @@ On multiarch system you should be able to install those be appending the architecture name after the package (example for ARM64): $ sudo apt-get install libfdt-dev:arm64 -PowerPC and ARM/ARM64 require libfdt to be installed. If you cannot use +PowerPC, ARM/ARM64 and RISC-V require libfdt to be installed. If you cannot use precompiled mulitarch packages, you could either copy the required header and library files from an installed target system into the SYSROOT (you will need /usr/include/*fdt*.h and /usr/lib64/libfdt-v.v.v.so and its symlinks), or you diff --git a/Makefile b/Makefile index bb7ad3e..817f45c 100644 --- a/Makefile +++ b/Makefile @@ -105,7 +105,8 @@ OBJS += virtio/mmio.o # Translate uname -m into ARCH string ARCH ?= $(shell uname -m | sed -e s/i.86/i386/ -e s/ppc.*/powerpc/ \ - -e s/armv.*/arm/ -e s/aarch64.*/arm64/ -e s/mips64/mips/) + -e s/armv.*/arm/ -e s/aarch64.*/arm64/ -e s/mips64/mips/ \ + -e s/riscv64/riscv/ -e s/riscv32/riscv/) ifeq ($(ARCH),i386) ARCH := x86 @@ -193,6 +194,24 @@ ifeq ($(ARCH),mips) OBJS += mips/kvm.o OBJS += mips/kvm-cpu.o endif + +# RISC-V (RV32 and RV64) +ifeq ($(ARCH),riscv) + DEFINES += -DCONFIG_RISCV + ARCH_INCLUDE := riscv/include + OBJS += riscv/ioport.o + OBJS += riscv/irq.o + OBJS += riscv/kvm.o + OBJS += riscv/kvm-cpu.o + ifeq ($(RISCV_XLEN),32) + CFLAGS += -mabi=ilp32d -march=rv32gc + endif + ifeq ($(RISCV_XLEN),64) + CFLAGS += -mabi=lp64d -march=rv64gc + endif + + ARCH_WANT_LIBFDT := y +endif ### ifeq (,$(ARCH_INCLUDE)) diff --git a/riscv/include/asm/kvm.h b/riscv/include/asm/kvm.h new file mode 100644 index 0000000..f808ad1 --- /dev/null +++ b/riscv/include/asm/kvm.h @@ -0,0 +1,128 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +/* + * Copyright (C) 2019 Western Digital Corporation or its affiliates. + * + * Authors: + * Anup Patel + */ + +#ifndef __LINUX_KVM_RISCV_H +#define __LINUX_KVM_RISCV_H + +#ifndef __ASSEMBLY__ + +#include +#include + +#define __KVM_HAVE_READONLY_MEM + +#define KVM_COALESCED_MMIO_PAGE_OFFSET 1 + +#define KVM_INTERRUPT_SET -1U +#define KVM_INTERRUPT_UNSET -2U + +/* for KVM_GET_REGS and KVM_SET_REGS */ +struct kvm_regs { +}; + +/* for KVM_GET_FPU and KVM_SET_FPU */ +struct kvm_fpu { +}; + +/* KVM Debug exit structure */ +struct kvm_debug_exit_arch { +}; + +/* for KVM_SET_GUEST_DEBUG */ +struct kvm_guest_debug_arch { +}; + +/* definition of registers in kvm_run */ +struct kvm_sync_regs { +}; + +/* for KVM_GET_SREGS and KVM_SET_SREGS */ +struct kvm_sregs { +}; + +/* CONFIG registers for KVM_GET_ONE_REG and KVM_SET_ONE_REG */ +struct kvm_riscv_config { + unsigned long isa; +}; + +/* CORE registers for KVM_GET_ONE_REG and KVM_SET_ONE_REG */ +struct kvm_riscv_core { + struct user_regs_struct regs; + unsigned long mode; +}; + +/* Possible privilege modes for kvm_riscv_core */ +#define KVM_RISCV_MODE_S 1 +#define KVM_RISCV_MODE_U 0 + +/* CSR registers for KVM_GET_ONE_REG and KVM_SET_ONE_REG */ +struct kvm_riscv_csr { + unsigned long sstatus; + unsigned long sie; + unsigned long stvec; + unsigned long sscratch; + unsigned long sepc; + unsigned long scause; + unsigned long stval; + unsigned long sip; + unsigned long satp; + unsigned long scounteren; +}; + +/* TIMER registers for KVM_GET_ONE_REG and KVM_SET_ONE_REG */ +struct kvm_riscv_timer { + __u64 frequency; + __u64 time; + __u64 compare; + __u64 state; +}; + +/* Possible states for kvm_riscv_timer */ +#define KVM_RISCV_TIMER_STATE_OFF 0 +#define KVM_RISCV_TIMER_STATE_ON 1 + +#define KVM_REG_SIZE(id) \ + (1U << (((id) & KVM_REG_SIZE_MASK) >> KVM_REG_SIZE_SHIFT)) + +/* If you need to interpret the index values, here is the key: */ +#define KVM_REG_RISCV_TYPE_MASK 0x00000000FF000000 +#define KVM_REG_RISCV_TYPE_SHIFT 24 + +/* Config registers are mapped as type 1 */ +#define KVM_REG_RISCV_CONFIG (0x01 << KVM_REG_RISCV_TYPE_SHIFT) +#define KVM_REG_RISCV_CONFIG_REG(name) \ + (offsetof(struct kvm_riscv_config, name) / sizeof(unsigned long)) + +/* Core registers are mapped as type 2 */ +#define KVM_REG_RISCV_CORE (0x02 << KVM_REG_RISCV_TYPE_SHIFT) +#define KVM_REG_RISCV_CORE_REG(name) \ + (offsetof(struct kvm_riscv_core, name) / sizeof(unsigned long)) + +/* Control and status registers are mapped as type 3 */ +#define KVM_REG_RISCV_CSR (0x03 << KVM_REG_RISCV_TYPE_SHIFT) +#define KVM_REG_RISCV_CSR_REG(name) \ + (offsetof(struct kvm_riscv_csr, name) / sizeof(unsigned long)) + +/* Timer registers are mapped as type 4 */ +#define KVM_REG_RISCV_TIMER (0x04 << KVM_REG_RISCV_TYPE_SHIFT) +#define KVM_REG_RISCV_TIMER_REG(name) \ + (offsetof(struct kvm_riscv_timer, name) / sizeof(__u64)) + +/* F extension registers are mapped as type 5 */ +#define KVM_REG_RISCV_FP_F (0x05 << KVM_REG_RISCV_TYPE_SHIFT) +#define KVM_REG_RISCV_FP_F_REG(name) \ + (offsetof(struct __riscv_f_ext_state, name) / sizeof(__u32)) + +/* D extension registers are mapped as type 6 */ +#define KVM_REG_RISCV_FP_D (0x06 << KVM_REG_RISCV_TYPE_SHIFT) +#define KVM_REG_RISCV_FP_D_REG(name) \ + (offsetof(struct __riscv_d_ext_state, name) / sizeof(__u64)) + +#endif + +#endif /* __LINUX_KVM_RISCV_H */ diff --git a/riscv/include/kvm/barrier.h b/riscv/include/kvm/barrier.h new file mode 100644 index 0000000..235f610 --- /dev/null +++ b/riscv/include/kvm/barrier.h @@ -0,0 +1,14 @@ +#ifndef KVM__KVM_BARRIER_H +#define KVM__KVM_BARRIER_H + +#define nop() __asm__ __volatile__ ("nop") + +#define RISCV_FENCE(p, s) \ + __asm__ __volatile__ ("fence " #p "," #s : : : "memory") + +/* These barriers need to enforce ordering on both devices or memory. */ +#define mb() RISCV_FENCE(iorw,iorw) +#define rmb() RISCV_FENCE(ir,ir) +#define wmb() RISCV_FENCE(ow,ow) + +#endif /* KVM__KVM_BARRIER_H */ diff --git a/riscv/include/kvm/fdt-arch.h b/riscv/include/kvm/fdt-arch.h new file mode 100644 index 0000000..9450fc5 --- /dev/null +++ b/riscv/include/kvm/fdt-arch.h @@ -0,0 +1,4 @@ +#ifndef KVM__KVM_FDT_H +#define KVM__KVM_FDT_H + +#endif /* KVM__KVM_FDT_H */ diff --git a/riscv/include/kvm/kvm-arch.h b/riscv/include/kvm/kvm-arch.h new file mode 100644 index 0000000..469fe4f --- /dev/null +++ b/riscv/include/kvm/kvm-arch.h @@ -0,0 +1,66 @@ +#ifndef KVM__KVM_ARCH_H +#define KVM__KVM_ARCH_H + +#include +#include +#include +#include + +#define RISCV_IOPORT 0x00000000ULL +#define RISCV_IOPORT_SIZE SZ_64K +#define RISCV_PLIC 0x0c000000ULL +#define RISCV_PLIC_SIZE SZ_64M +#define RISCV_MMIO 0x10000000ULL +#define RISCV_MMIO_SIZE SZ_512M +#define RISCV_PCI 0x30000000ULL +/* + * KVMTOOL emulates legacy PCI config space with 24bits device address + * so 16M is sufficient but we reserve 256M to keep it future ready for + * PCIe config space with 28bits device address. + */ +#define RISCV_PCI_CFG_SIZE SZ_256M +#define RISCV_PCI_MMIO_SIZE SZ_1G +#define RISCV_PCI_SIZE (RISCV_PCI_CFG_SIZE + RISCV_PCI_MMIO_SIZE) + +#define RISCV_RAM 0x80000000ULL + +#define RISCV_LOMAP_MAX_MEMORY ((1ULL << 32) - RISCV_RAM) +#define RISCV_HIMAP_MAX_MEMORY ((1ULL << 40) - RISCV_RAM) + +#if __riscv_xlen == 64 +#define RISCV_MAX_MEMORY(kvm) RISCV_HIMAP_MAX_MEMORY +#elif __riscv_xlen == 32 +#define RISCV_MAX_MEMORY(kvm) RISCV_LOMAP_MAX_MEMORY +#endif + +#define KVM_IOPORT_AREA RISCV_IOPORT +#define KVM_PCI_CFG_AREA RISCV_PCI +#define KVM_PCI_MMIO_AREA (KVM_PCI_CFG_AREA + RISCV_PCI_CFG_SIZE) +#define KVM_VIRTIO_MMIO_AREA RISCV_MMIO + +#define KVM_IOEVENTFD_HAS_PIO 0 + +#define KVM_IRQ_OFFSET 1 + +#define KVM_VM_TYPE 0 + +#define VIRTIO_DEFAULT_TRANS(kvm) VIRTIO_MMIO + +#define VIRTIO_RING_ENDIAN VIRTIO_ENDIAN_LE + +#define ARCH_HAS_PCI_EXP 1 + +struct kvm; + +struct kvm_arch { +}; + +static inline bool riscv_addr_in_ioport_region(u64 phys_addr) +{ + u64 limit = KVM_IOPORT_AREA + RISCV_IOPORT_SIZE; + return phys_addr >= KVM_IOPORT_AREA && phys_addr < limit; +} + +enum irq_type; + +#endif /* KVM__KVM_ARCH_H */ diff --git a/riscv/include/kvm/kvm-config-arch.h b/riscv/include/kvm/kvm-config-arch.h new file mode 100644 index 0000000..60c7333 --- /dev/null +++ b/riscv/include/kvm/kvm-config-arch.h @@ -0,0 +1,9 @@ +#ifndef KVM__KVM_CONFIG_ARCH_H +#define KVM__KVM_CONFIG_ARCH_H + +#include "kvm/parse-options.h" + +struct kvm_config_arch { +}; + +#endif /* KVM__KVM_CONFIG_ARCH_H */ diff --git a/riscv/include/kvm/kvm-cpu-arch.h b/riscv/include/kvm/kvm-cpu-arch.h new file mode 100644 index 0000000..ae6ae0a --- /dev/null +++ b/riscv/include/kvm/kvm-cpu-arch.h @@ -0,0 +1,47 @@ +#ifndef KVM__KVM_CPU_ARCH_H +#define KVM__KVM_CPU_ARCH_H + +#include +#include +#include + +#include "kvm/kvm.h" + +struct kvm_cpu { + pthread_t thread; + + unsigned long cpu_id; + + struct kvm *kvm; + int vcpu_fd; + struct kvm_run *kvm_run; + struct kvm_cpu_task *task; + + u8 is_running; + u8 paused; + u8 needs_nmi; + + struct kvm_coalesced_mmio_ring *ring; +}; + +static inline bool kvm_cpu__emulate_io(struct kvm_cpu *vcpu, u16 port, + void *data, int direction, + int size, u32 count) +{ + return false; +} + +static inline bool kvm_cpu__emulate_mmio(struct kvm_cpu *vcpu, u64 phys_addr, + u8 *data, u32 len, u8 is_write) +{ + if (riscv_addr_in_ioport_region(phys_addr)) { + int direction = is_write ? KVM_EXIT_IO_OUT : KVM_EXIT_IO_IN; + u16 port = (phys_addr - KVM_IOPORT_AREA) & USHRT_MAX; + + return kvm__emulate_io(vcpu, port, data, direction, len, 1); + } + + return kvm__emulate_mmio(vcpu, phys_addr, data, len, is_write); +} + +#endif /* KVM__KVM_CPU_ARCH_H */ diff --git a/riscv/ioport.c b/riscv/ioport.c new file mode 100644 index 0000000..24092c9 --- /dev/null +++ b/riscv/ioport.c @@ -0,0 +1,7 @@ +#include "kvm/ioport.h" +#include "kvm/irq.h" + +void ioport__map_irq(u8 *irq) +{ + *irq = irq__alloc_line(); +} diff --git a/riscv/irq.c b/riscv/irq.c new file mode 100644 index 0000000..8e605ef --- /dev/null +++ b/riscv/irq.c @@ -0,0 +1,13 @@ +#include "kvm/kvm.h" +#include "kvm/kvm-cpu.h" +#include "kvm/irq.h" + +void kvm__irq_line(struct kvm *kvm, int irq, int level) +{ + /* TODO: */ +} + +void kvm__irq_trigger(struct kvm *kvm, int irq) +{ + /* TODO: */ +} diff --git a/riscv/kvm-cpu.c b/riscv/kvm-cpu.c new file mode 100644 index 0000000..e4b8fa5 --- /dev/null +++ b/riscv/kvm-cpu.c @@ -0,0 +1,64 @@ +#include "kvm/kvm-cpu.h" +#include "kvm/kvm.h" +#include "kvm/virtio.h" +#include "kvm/term.h" + +#include + +static int debug_fd; + +void kvm_cpu__set_debug_fd(int fd) +{ + debug_fd = fd; +} + +int kvm_cpu__get_debug_fd(void) +{ + return debug_fd; +} + +struct kvm_cpu *kvm_cpu__arch_init(struct kvm *kvm, unsigned long cpu_id) +{ + /* TODO: */ + return NULL; +} + +void kvm_cpu__arch_nmi(struct kvm_cpu *cpu) +{ +} + +void kvm_cpu__delete(struct kvm_cpu *vcpu) +{ + /* TODO: */ +} + +bool kvm_cpu__handle_exit(struct kvm_cpu *vcpu) +{ + /* TODO: */ + return false; +} + +void kvm_cpu__show_page_tables(struct kvm_cpu *vcpu) +{ + /* TODO: */ +} + +void kvm_cpu__reset_vcpu(struct kvm_cpu *vcpu) +{ + /* TODO: */ +} + +int kvm_cpu__get_endianness(struct kvm_cpu *vcpu) +{ + return VIRTIO_ENDIAN_LE; +} + +void kvm_cpu__show_code(struct kvm_cpu *vcpu) +{ + /* TODO: */ +} + +void kvm_cpu__show_registers(struct kvm_cpu *vcpu) +{ + /* TODO: */ +} diff --git a/riscv/kvm.c b/riscv/kvm.c new file mode 100644 index 0000000..e816ef5 --- /dev/null +++ b/riscv/kvm.c @@ -0,0 +1,61 @@ +#include "kvm/kvm.h" +#include "kvm/util.h" +#include "kvm/fdt.h" + +#include +#include +#include + +struct kvm_ext kvm_req_ext[] = { + { DEFINE_KVM_EXT(KVM_CAP_ONE_REG) }, + { 0, 0 }, +}; + +bool kvm__arch_cpu_supports_vm(void) +{ + /* The KVM capability check is enough. */ + return true; +} + +void kvm__init_ram(struct kvm *kvm) +{ + /* TODO: */ +} + +void kvm__arch_delete_ram(struct kvm *kvm) +{ + /* TODO: */ +} + +void kvm__arch_read_term(struct kvm *kvm) +{ + /* TODO: */ +} + +void kvm__arch_set_cmdline(char *cmdline, bool video) +{ + /* TODO: */ +} + +void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size) +{ + /* TODO: */ +} + +bool kvm__arch_load_kernel_image(struct kvm *kvm, int fd_kernel, int fd_initrd, + const char *kernel_cmdline) +{ + /* TODO: */ + return true; +} + +bool kvm__load_firmware(struct kvm *kvm, const char *firmware_filename) +{ + /* TODO: Firmware loading to be supported later. */ + return false; +} + +int kvm__arch_setup_firmware(struct kvm *kvm) +{ + return 0; +} diff --git a/util/update_headers.sh b/util/update_headers.sh index 049dfe4..5f9cd32 100755 --- a/util/update_headers.sh +++ b/util/update_headers.sh @@ -36,7 +36,7 @@ copy_optional_arch () { fi } -for arch in arm64 mips powerpc x86 +for arch in arm64 mips powerpc riscv x86 do case "$arch" in arm64) KVMTOOL_PATH=arm/aarch64 From patchwork Mon Sep 27 11:42:22 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anup Patel X-Patchwork-Id: 12519637 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B7A1DC433F5 for ; Mon, 27 Sep 2021 11:43:13 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A48BC60F6C for ; Mon, 27 Sep 2021 11:43:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234228AbhI0Lou (ORCPT ); Mon, 27 Sep 2021 07:44:50 -0400 Received: from esa1.hgst.iphmx.com ([68.232.141.245]:50202 "EHLO esa1.hgst.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234368AbhI0Loe (ORCPT ); Mon, 27 Sep 2021 07:44:34 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=wdc.com; i=@wdc.com; q=dns/txt; s=dkim.wdc.com; t=1632742977; x=1664278977; h=from:to:cc:subject:date:message-id:in-reply-to: references:content-transfer-encoding:mime-version; bh=8sJKongyv38X9dKpS1HAiSrvranGdK7ToL3Rs+JN/9o=; b=eJ/XVhP3d6LugbJgG+uJePqmSExBXQETQBZ3hnOolMY3+YWnMh1LPNvx khAqlV/h7OK8e4aN5NMhnGDt5ex/Gvni4XFkzGQg4NTNzhObHankGelEx SjrJbMMgTFDSdNjnc2EmT9aWI/dKCfDv1KU1HRccWoe+Ftx4C4VH9Ywf6 a32aPJcg4QcDq8p9pNLctF11/vO3LHFlew1eHn1Lb0vTdsHsM74eEmcXh HxDDKtv2Ki/ivZzUki1isX1GSyZv5A+tAHLmpNXBjyr4tnmeEG0ovuTN9 UsNUl1yT14H0ZKfUw8T5wgjmM9gmsRAxI8dOgIVUKPKqItnpAoJpG1g+g w==; X-IronPort-AV: E=Sophos;i="5.85,326,1624291200"; d="scan'208";a="292706608" Received: from mail-bn8nam12lp2177.outbound.protection.outlook.com (HELO NAM12-BN8-obe.outbound.protection.outlook.com) ([104.47.55.177]) by ob1.hgst.iphmx.com with ESMTP; 27 Sep 2021 19:42:55 +0800 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=CO3ofSJq6YnNf5ksQOGj25ar2Wa6bVk3AW42ZfzIedwfMSgMtv0tj0qQHIJnqejzWL249rjdaiQy5q+/o9QT/njXiTSJ7MIqX+iw1zkEBcGUqJcLJWJf2yCoE/UyLhyO6/M59czYH8SpXTC7LTKV8bcC0BjF6nQimexQpyrLwAQKv1cs1j1c6y7XPyg1UbQn360RFutgoJIVpL5rEtJq0e3iVbEDzZZOewi20U/kGFMQrsY9x9wmJcNL+Jsl0oW3kkc7NBFO4xAPpSkrtTKqgg+aWewdQp6GU96knEF4N+qYJVQJqT2QjBakpJZp15ULtfRGVrLXKofMP8iJI0HPNQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=IxOKTE7vBtafxQW3/p1xsg+vDHiANbdGFrid+hSkks4=; b=Hp8Ll5RzNXVWPLbHUumk1Gtcj31X+zCC96NIjbHINZF3jmRtPlQdaVmBciOiv8YIcITKMLm0Px+tQmWxDHioKz2hwb2bP0HaVk9vBM2UyhBRCMPC0JdPyln4+fLK/Wteq7lOHz6gQqrJ62Ug9w6pd7X19u6lOGqZmZKhLywQ9K4Mfi8yTAiOXURJNyzJlRR297VzSdHzi2etOJqqYVbESbNEi71LWxmmBDifxip0g2OXtNzfk09THTZ5iQhJOuwm0Y4fXhtSqDcubWueGAoyWXKQadUuJZuVFzTVBgAj1luWoEEwM8CPm4SpL+5hmatYEc6fGwL5CTmNujSHnugljw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=wdc.com; dmarc=pass action=none header.from=wdc.com; dkim=pass header.d=wdc.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sharedspace.onmicrosoft.com; s=selector2-sharedspace-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=IxOKTE7vBtafxQW3/p1xsg+vDHiANbdGFrid+hSkks4=; b=b+ZQsWz49HkT6n6Pn3AkiEMcdICfxX+UP2D0m4WNqe7K2fcXdVb+Ij/MUT5z+YarmAc60QnDU8jhEkjl6nlLvdHixECOeBGLKdbwv1nP93oHqexzWZLvRU4OTZrxOmJ6l8hamUidygRdOwxBaiugFUMp2Jeu+4rTnKxmYpzrof8= Authentication-Results: kernel.org; dkim=none (message not signed) header.d=none;kernel.org; dmarc=none action=none header.from=wdc.com; Received: from CO6PR04MB7812.namprd04.prod.outlook.com (2603:10b6:303:138::6) by CO6PR04MB7841.namprd04.prod.outlook.com (2603:10b6:5:358::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4544.13; Mon, 27 Sep 2021 11:42:55 +0000 Received: from CO6PR04MB7812.namprd04.prod.outlook.com ([fe80::6830:650b:8265:af0b]) by CO6PR04MB7812.namprd04.prod.outlook.com ([fe80::6830:650b:8265:af0b%6]) with mapi id 15.20.4544.021; Mon, 27 Sep 2021 11:42:54 +0000 From: Anup Patel To: Will Deacon Cc: Paolo Bonzini , Atish Patra , Alistair Francis , Anup Patel , kvm@vger.kernel.org, kvm-riscv@lists.infradead.org, Anup Patel Subject: [PATCH v9 3/8] riscv: Implement Guest/VM arch functions Date: Mon, 27 Sep 2021 17:12:22 +0530 Message-Id: <20210927114227.1089403-4-anup.patel@wdc.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210927114227.1089403-1-anup.patel@wdc.com> References: <20210927114227.1089403-1-anup.patel@wdc.com> X-ClientProxiedBy: MA1PR01CA0173.INDPRD01.PROD.OUTLOOK.COM (2603:1096:a01:d::14) To CO6PR04MB7812.namprd04.prod.outlook.com (2603:10b6:303:138::6) MIME-Version: 1.0 Received: from wdc.com (122.179.75.205) by MA1PR01CA0173.INDPRD01.PROD.OUTLOOK.COM (2603:1096:a01:d::14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4544.14 via Frontend Transport; Mon, 27 Sep 2021 11:42:52 +0000 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 94cc3f79-aa59-4d20-af3d-08d981abf1b6 X-MS-TrafficTypeDiagnostic: CO6PR04MB7841: X-MS-Exchange-Transport-Forked: True X-Microsoft-Antispam-PRVS: WDCIPOUTBOUND: EOP-TRUE X-MS-Oob-TLC-OOBClassifiers: OLM:8882; X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: nTQ3FBm3+3LCWFU1yWOCwHGTzPE46JV+pl35u/ecGnEYjbWgF9og/6dtElpxxMC5QpvGXdowUfDoLuMGDmZYQpX/LOKqvaTNXeMC9SmgCeURWJlCT/21eIiauAqCKgpJOxFbms3NXoK25FlfsVIurDyprTRjOJgyT3ck22sAuGeUZ14+OfGUBn9op59lhI8sYi7u/k9vsjoo9nkXKpUd0d6AN2dtJ9rjJ9664dIYeXhT6GbsT+JdVTEThOgmIp13rasAp2Hi22xWGiL8lzxjHeGv8dl+7YOgPrloYa8PftOC4kS2hePiW83g074Db4+2Wjh1QoOacalh9EFrwXy5HWxAOxByGRR+CIdAelWSLcdGONZ2bW7vaP4KPZTRlhdSX9xgLSkmQ8vgPhnhJHk67+0qahcYX413c7FFVObemlRNQrw3ti2pG4kGacUnktOHji/blyq5Ildms+KNTL2AYvfiKBwB/SggIH9D/+OXtEH7bXosHItm0VhUdIFFluO+JfX6adETTCoLGe3yM7LuvnZH8Q4VHoBuqjudUFHn25aXZNzWGw1L8PNgN4uJ2PQrKCDEu9lItr0QXYvEaggnlRPIKAmPn0VdeAv43z4+hACwuJsexDCQFnPL8Fc3PQAT4BaHILxIvSQ/uLYzENGUkOVJk/nPuH6WeHd7RaM8W0oPAzsxbUvOhzaujNuIQ3f7nL3N3TLtfbgc9NEqdnKKvw== X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:CO6PR04MB7812.namprd04.prod.outlook.com;PTR:;CAT:NONE;SFS:(4636009)(366004)(54906003)(316002)(5660300002)(1076003)(66556008)(83380400001)(66946007)(66476007)(36756003)(38100700002)(38350700002)(55016002)(86362001)(508600001)(6916009)(44832011)(8886007)(6666004)(2906002)(8676002)(956004)(2616005)(7696005)(8936002)(4326008)(26005)(52116002)(186003);DIR:OUT;SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: gVY97NcZAO1H4adtfFH6Rl8HSufciIlpGWH4gR7cIcvextXSEE3KrqcbKAFOuuWjeRXkd6zPFbyqUfw0VQAH0kdATTc3iKFHzgTEFzuqD4gVAKNd3nfIf5ctfHLu/RiDefJzaeDEyhGlThxyAtcqJo482NsMYmhEwHsMGsCdrIkrLx9R0aAlXnvyDD0GYFhK/qpcL/kTKXIxuZDjd/Uwbph26DmcJ6jznpFEt7mVpslP1JrwZT4CAScAMsIFCJb1aI+fr0+MSMXKjNs6lackkBuX3zRKXrbDp9rraJWZj7SRQYbqLjCq7ybTxmJ8uRVSEOgTtUzDKPZkW5wbPPM2vb+5jRwCU4VpGGkgPdfCKyHjEgETJW7s3NwIOxDpsgFQjWApIiDcxYYdHdxcb22ulOUUdKZaGBpBjIAI+wAVkgn14UAmcyauZmz8nnE8vq9GMCy3LZXu7ilX1zaXW2bRx0OLnlUQWKgLG66rYTKbAtU0liwIA8DJLy6CLzBN5moJBVFPdMGXPbC6qNVbjobmtxEccsD9v61aMGO+z4pGpTWAXYUbQSLetZM9U+ssGlZes4skySHKhCx2jC19V74xilDpnEJjdATs39nM4xrnFdK/fuNUc7dTLoUW5wYLqwauSMz5iKY/KphC2e+U0bShD1djkAs2aaxXvEHlCuu/N75SYn5NUUdXmSO6gULzjbNFMhU6nnwCiJ/zYru+Mbe/XZa/BlQb2fEhLhp9wn220cSpgJcNjmKapX2nSIL+f/uHHpRyvx/EahYuLmXCRI6tvglW21gFRU7mNJYMAP7CE4dkTbEnAZs3rqt2P0YhVRc/WvODXO5NyxhXfaKgBVBKRqH7CVUkNE2kdUhxfabqoLQgnk8J0byWvY7eV1R9iPCuyWX7EqkcscGUbuSpPoDkCCZIYndBxP5C84OJcek95oJUOAuUhyjwZOxP6zn6YvhXIXz03sYTtNCG5kRGXgJRXlOCOlubZ35kRdAkkfYBYPIIJtNYLIkX2Mh1vm4yuzd2zHbXkLRN5ezcUV3DhtSk4C1Tv5QpnE9xk6GQPwu4qJMc4YZz2A7Kd9zcOUeBdQ+UwI6KuNudk9WcEIpaSDH96E1WSWNubhwO3diR8hD3zGcLwk588XcdYroAWGHJrUZSZysH/qDoyp5SwP0NOR8uR9R2tR6aGgJ7Z1zFhY8YdYQlmkcweWfPaQEuaYTG6HTfe6HYUjAvpEp912VQqq819wLO171+q9oWeH3NVDZEIazENNWHTgcZCvJIxscabIaSNnJhHMo+H1oYm4AeUwci7yfWUXLUgzfOoaHSBwax2KI0GX8oIzqYayZSwl0kgKfm X-OriginatorOrg: wdc.com X-MS-Exchange-CrossTenant-Network-Message-Id: 94cc3f79-aa59-4d20-af3d-08d981abf1b6 X-MS-Exchange-CrossTenant-AuthSource: CO6PR04MB7812.namprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 27 Sep 2021 11:42:54.7344 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: b61c8803-16f3-4c35-9b17-6f65f441df86 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: YihqQyUiEHG2Xutk/SpJFqSIehFn7t6XB5X6lfkVkstLq4GVV5plYhlKIPeGFjhS8iFIxQqo9X4dEt6JUKG8uQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: CO6PR04MB7841 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org This patch implements all kvm__arch_ Guest/VM arch functions. These functions mostly deal with: 1. Guest/VM RAM initialization 2. Updating terminals on character read 3. Loading kernel and initrd images Firmware loading is not implemented currently because initially we will be booting kernel directly without any bootloader. In future, we will certainly support firmware loading. Signed-off-by: Anup Patel --- riscv/include/kvm/kvm-arch.h | 15 +++++ riscv/kvm.c | 125 +++++++++++++++++++++++++++++++++-- 2 files changed, 134 insertions(+), 6 deletions(-) diff --git a/riscv/include/kvm/kvm-arch.h b/riscv/include/kvm/kvm-arch.h index 469fe4f..529d5b3 100644 --- a/riscv/include/kvm/kvm-arch.h +++ b/riscv/include/kvm/kvm-arch.h @@ -53,6 +53,21 @@ struct kvm; struct kvm_arch { + /* + * We may have to align the guest memory for virtio, so keep the + * original pointers here for munmap. + */ + void *ram_alloc_start; + u64 ram_alloc_size; + + /* + * Guest addresses for memory layout. + */ + u64 memory_guest_start; + u64 kern_guest_start; + u64 initrd_guest_start; + u64 initrd_size; + u64 dtb_guest_start; }; static inline bool riscv_addr_in_ioport_region(u64 phys_addr) diff --git a/riscv/kvm.c b/riscv/kvm.c index e816ef5..84e0277 100644 --- a/riscv/kvm.c +++ b/riscv/kvm.c @@ -1,5 +1,7 @@ #include "kvm/kvm.h" #include "kvm/util.h" +#include "kvm/8250-serial.h" +#include "kvm/virtio-console.h" #include "kvm/fdt.h" #include @@ -19,33 +21,144 @@ bool kvm__arch_cpu_supports_vm(void) void kvm__init_ram(struct kvm *kvm) { - /* TODO: */ + int err; + u64 phys_start, phys_size; + void *host_mem; + + phys_start = RISCV_RAM; + phys_size = kvm->ram_size; + host_mem = kvm->ram_start; + + err = kvm__register_ram(kvm, phys_start, phys_size, host_mem); + if (err) + die("Failed to register %lld bytes of memory at physical " + "address 0x%llx [err %d]", phys_size, phys_start, err); + + kvm->arch.memory_guest_start = phys_start; } void kvm__arch_delete_ram(struct kvm *kvm) { - /* TODO: */ + munmap(kvm->arch.ram_alloc_start, kvm->arch.ram_alloc_size); } void kvm__arch_read_term(struct kvm *kvm) { - /* TODO: */ + serial8250__update_consoles(kvm); + virtio_console__inject_interrupt(kvm); } void kvm__arch_set_cmdline(char *cmdline, bool video) { - /* TODO: */ } void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size) { - /* TODO: */ + /* + * Allocate guest memory. We must align our buffer to 64K to + * correlate with the maximum guest page size for virtio-mmio. + * If using THP, then our minimal alignment becomes 2M. + * 2M trumps 64K, so let's go with that. + */ + kvm->ram_size = min(ram_size, (u64)RISCV_MAX_MEMORY(kvm)); + kvm->arch.ram_alloc_size = kvm->ram_size + SZ_2M; + kvm->arch.ram_alloc_start = mmap_anon_or_hugetlbfs(kvm, hugetlbfs_path, + kvm->arch.ram_alloc_size); + + if (kvm->arch.ram_alloc_start == MAP_FAILED) + die("Failed to map %lld bytes for guest memory (%d)", + kvm->arch.ram_alloc_size, errno); + + kvm->ram_start = (void *)ALIGN((unsigned long)kvm->arch.ram_alloc_start, + SZ_2M); + + madvise(kvm->arch.ram_alloc_start, kvm->arch.ram_alloc_size, + MADV_MERGEABLE); + + madvise(kvm->arch.ram_alloc_start, kvm->arch.ram_alloc_size, + MADV_HUGEPAGE); } +#define FDT_ALIGN SZ_4M +#define INITRD_ALIGN 8 bool kvm__arch_load_kernel_image(struct kvm *kvm, int fd_kernel, int fd_initrd, const char *kernel_cmdline) { - /* TODO: */ + void *pos, *kernel_end, *limit; + unsigned long guest_addr, kernel_offset; + ssize_t file_size; + + /* + * Linux requires the initrd and dtb to be mapped inside lowmem, + * so we can't just place them at the top of memory. + */ + limit = kvm->ram_start + min(kvm->ram_size, (u64)SZ_256M) - 1; + +#if __riscv_xlen == 64 + /* Linux expects to be booted at 2M boundary for RV64 */ + kernel_offset = 0x200000; +#else + /* Linux expects to be booted at 4M boundary for RV32 */ + kernel_offset = 0x400000; +#endif + + pos = kvm->ram_start + kernel_offset; + kvm->arch.kern_guest_start = host_to_guest_flat(kvm, pos); + file_size = read_file(fd_kernel, pos, limit - pos); + if (file_size < 0) { + if (errno == ENOMEM) + die("kernel image too big to fit in guest memory."); + + die_perror("kernel read"); + } + kernel_end = pos + file_size; + pr_debug("Loaded kernel to 0x%llx (%zd bytes)", + kvm->arch.kern_guest_start, file_size); + + /* Place FDT just after kernel at FDT_ALIGN address */ + pos = kernel_end + FDT_ALIGN; + guest_addr = ALIGN(host_to_guest_flat(kvm, pos), FDT_ALIGN); + pos = guest_flat_to_host(kvm, guest_addr); + if (pos < kernel_end) + die("fdt overlaps with kernel image."); + + kvm->arch.dtb_guest_start = guest_addr; + pr_debug("Placing fdt at 0x%llx - 0x%llx", + kvm->arch.dtb_guest_start, + host_to_guest_flat(kvm, limit)); + + /* ... and finally the initrd, if we have one. */ + if (fd_initrd != -1) { + struct stat sb; + unsigned long initrd_start; + + if (fstat(fd_initrd, &sb)) + die_perror("fstat"); + + pos = limit - (sb.st_size + INITRD_ALIGN); + guest_addr = ALIGN(host_to_guest_flat(kvm, pos), INITRD_ALIGN); + pos = guest_flat_to_host(kvm, guest_addr); + if (pos < kernel_end) + die("initrd overlaps with kernel image."); + + initrd_start = guest_addr; + file_size = read_file(fd_initrd, pos, limit - pos); + if (file_size == -1) { + if (errno == ENOMEM) + die("initrd too big to fit in guest memory."); + + die_perror("initrd read"); + } + + kvm->arch.initrd_guest_start = initrd_start; + kvm->arch.initrd_size = file_size; + pr_debug("Loaded initrd to 0x%llx (%llu bytes)", + kvm->arch.initrd_guest_start, + kvm->arch.initrd_size); + } else { + kvm->arch.initrd_size = 0; + } + return true; } From patchwork Mon Sep 27 11:42:23 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anup Patel X-Patchwork-Id: 12519639 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C8432C4332F for ; Mon, 27 Sep 2021 11:43:15 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A92AA60F58 for ; Mon, 27 Sep 2021 11:43:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234069AbhI0Low (ORCPT ); Mon, 27 Sep 2021 07:44:52 -0400 Received: from esa4.hgst.iphmx.com ([216.71.154.42]:27022 "EHLO esa4.hgst.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234265AbhI0Loh (ORCPT ); Mon, 27 Sep 2021 07:44:37 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=wdc.com; i=@wdc.com; q=dns/txt; s=dkim.wdc.com; t=1632742980; x=1664278980; h=from:to:cc:subject:date:message-id:in-reply-to: references:content-transfer-encoding:mime-version; bh=BQZ1Za9H9U0aUcvgBReFX+tUxwlb3hEC3mtu5JmRPXg=; b=IiFM/b6GIH/2RYC3bKnNV+0JaLNcHkjeRrnqTwZurxcjwC8ITXVyMlHv Fsp/5840uUkQXV7WyXvFa+vb242fMTJfVCXUHISK9fxMApD37zZh+B65r lCmqpK3KS9/mtU1ZHwIzB2+mO4/AhEBPCuCox9SF7JNUr3j3+F8+3cF8A /S2BP5esk8TxIrW+Dacmo5BnabVNtDtbKh5lenEqdvitlhnZrUYxKefwa b9HfqCnhMg0FVU34J6KQPsU1IFNOTcFUV5DHBGxcpHD0/CsXx5BNmbB7g l6odGkyyVLoM+MGxRJ2aBCF2CGVAZ0+JlI4Zex5ySEIWCP08jcJc5frzi Q==; X-IronPort-AV: E=Sophos;i="5.85,326,1624291200"; d="scan'208";a="180126882" Received: from mail-bn8nam12lp2175.outbound.protection.outlook.com (HELO NAM12-BN8-obe.outbound.protection.outlook.com) ([104.47.55.175]) by ob1.hgst.iphmx.com with ESMTP; 27 Sep 2021 19:42:59 +0800 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=kMQNfE6lDDRR1h6LQbZqNkCkQYcrhp3veOSQpSaYPKpF1bHRoluamfnIPr4rbdoKjim2pFefzjN5vG+XMwmbZPTTB19kC35pCopMMGGeYuuaUAaehtiZaDYZpKra6A81UT3ZxfjVwHynJTB7usJF+ZHpPJVCQVntlJKt8ym0gQD5QHFRhHSAeV3obvuLZJEb/FTzIiTLMmcTwFGS9pQO5KSorioT1p93/lfC1a1P9NgKk3U6nZEeHUSdqgtOsq8mwuP+ZeCKfAj/CaDLUvfl4D/uckoCmoC6xb1f4WjbqHWX6bLbO9qSyEkUiqGhZMZlUYiMJ8Cz5ndLb8xq0eVWoQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=/IR3wBcbUaY52UvbQXJeYgkLVfOx+Vj1u/MVm22uS1s=; b=Ad6qxfHGWHyjKTRrrAZmLN8fjec9LyX2KpJW0UiFlrW2fLmLcOYKNpVj3X1CXhPN65Ite3tlsu8NPXEy7XiCm6KthyJ0jb7oVMjNyxqFOseMOLJl4Pnqz/3uTnB/R5FK7nae+1M0WQ7ftjGx5ARIOCtO971tOYe5kU7WXq4Q6XXsLF2mEgeNqTg8HpB43qBF87S3mj6YDcu06+iPmlbt5giLL7Iu65GC4nYyewlHryB2v5v1/RvsCWu/a2kTNZXoqozsOVuJYRjdvpT8BUK6cYijw8xbnTK0loM5Ea6da+u9X5M7ReiXw7DKRpu5jIaXPV0+a/dTio4ZGSVIMJEP3w== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=wdc.com; dmarc=pass action=none header.from=wdc.com; dkim=pass header.d=wdc.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sharedspace.onmicrosoft.com; s=selector2-sharedspace-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=/IR3wBcbUaY52UvbQXJeYgkLVfOx+Vj1u/MVm22uS1s=; b=jwt0ZPLuSjVyMCuXam1+CcklTVq25JwYQMrvn4gi0fG2V+RUaPzA0N3oLKUpUnQFEd1p0N2pdWiQ7KWv2OJGgHgDnkXCg0vUlt3eVFy/0BQMT42TvjiNsRoLUdny8nxhL+9H8SGIkDT7soY4DC4MMcHN2ArOsrzpZi/HxgEVs9A= Authentication-Results: kernel.org; dkim=none (message not signed) header.d=none;kernel.org; dmarc=none action=none header.from=wdc.com; Received: from CO6PR04MB7812.namprd04.prod.outlook.com (2603:10b6:303:138::6) by CO6PR04MB7841.namprd04.prod.outlook.com (2603:10b6:5:358::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4544.13; Mon, 27 Sep 2021 11:42:57 +0000 Received: from CO6PR04MB7812.namprd04.prod.outlook.com ([fe80::6830:650b:8265:af0b]) by CO6PR04MB7812.namprd04.prod.outlook.com ([fe80::6830:650b:8265:af0b%6]) with mapi id 15.20.4544.021; Mon, 27 Sep 2021 11:42:57 +0000 From: Anup Patel To: Will Deacon Cc: Paolo Bonzini , Atish Patra , Alistair Francis , Anup Patel , kvm@vger.kernel.org, kvm-riscv@lists.infradead.org, Anup Patel Subject: [PATCH v9 4/8] riscv: Implement Guest/VM VCPU arch functions Date: Mon, 27 Sep 2021 17:12:23 +0530 Message-Id: <20210927114227.1089403-5-anup.patel@wdc.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210927114227.1089403-1-anup.patel@wdc.com> References: <20210927114227.1089403-1-anup.patel@wdc.com> X-ClientProxiedBy: MA1PR01CA0173.INDPRD01.PROD.OUTLOOK.COM (2603:1096:a01:d::14) To CO6PR04MB7812.namprd04.prod.outlook.com (2603:10b6:303:138::6) MIME-Version: 1.0 Received: from wdc.com (122.179.75.205) by MA1PR01CA0173.INDPRD01.PROD.OUTLOOK.COM (2603:1096:a01:d::14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4544.14 via Frontend Transport; Mon, 27 Sep 2021 11:42:55 +0000 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 3cefe86f-35d4-457c-ce73-08d981abf35b X-MS-TrafficTypeDiagnostic: CO6PR04MB7841: X-MS-Exchange-Transport-Forked: True X-Microsoft-Antispam-PRVS: WDCIPOUTBOUND: EOP-TRUE X-MS-Oob-TLC-OOBClassifiers: OLM:6790; X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: t91vLeJlve0Jsri2+IZwrEjT2PI+mY1Gm0O4HdbUG0cHIMCcMXlQe3Z6KpuVWkOON2XuTRuOpNoo5Hl+H2DpWaCZVcxziZ9iPDhbmew4t6p6+ELW9IxgXdS+JGyc03XPVjPsm13ktsRya7Ra+JrRVFsC4NTUOx+PCs2lcrK+oKcPQHbERggVc3q+c8f0X4GKMQw6QnmSKUKUpHnQD4hnMP0+N72HB2aY3U9xvG8yhybOzLiwQLnEH8w0wZqJiPC7gHyjNpZpkDUI3bY05PN5/CJ3dKeJ79gBxwz76ju1j9ctnERkQEUNwKnTFRRJ+sHSiU2Fybky/+StmoJpy7vdbf80/NyqdMudPUpAuztHUbK92Cnls3a3seb1ASOOToUdLqfbPbD29swilmKE43Oi/wuG+R+O5s83no/1jS3mH7N+YqLki5/bNhRZygrV9EUZ5U6oYZeYg9db+gVGmVqgnZ2wBc5geAoUyIuFVtnBYTJEin5FUEJheL+kalr0IRW2ERC1eHRSERNzTdSWMjMZHvWl03ZYUMbXtBNgukgf3jJ980lUSgRo//HzSCjUSKBBUatt08pIBfPizwyqvSJNbEX6v10sCrl3o0OgpBSHigNfugCwXQ79/T/9RgKgOHhKzbcQGsQKi0znKm32cNQVCRhcXLpnk5r5e5EnQofyVJHDuKFKAJj6ifR64sojDOPwWGxFs2oOnLDuzSIwye7hAA== X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:CO6PR04MB7812.namprd04.prod.outlook.com;PTR:;CAT:NONE;SFS:(4636009)(366004)(54906003)(316002)(5660300002)(1076003)(66556008)(83380400001)(30864003)(66946007)(66476007)(36756003)(38100700002)(38350700002)(55016002)(86362001)(508600001)(6916009)(44832011)(8886007)(6666004)(2906002)(8676002)(956004)(2616005)(7696005)(8936002)(4326008)(26005)(52116002)(186003);DIR:OUT;SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: wcAJ4sf2xdhSuPqj1jE8aln6B53pMkX8yhBivTEUlMSklScCbjiDjUF8n4S0cbiHlS1uTtxVUP7MpshtHjygE6AmJDIbkRlBtYW053OUYcTjrPABh5Zf0w5o9gODsaBoLrWREApP48HLbJrFoeRPC8UFUwcX9+HGLLBCjHxZTX0EcncWdKR2EKdl34h5w++KrCxDb6q19kPizNsxbexNkVJVefWenH5Cd+kY8tlzXmLs1WtkMKNM+CSPPkUTDPnH861fIBm2Ny2KHNcszEyqd8ZE6HAUyWd3HOsG4XevHTJgtmQEVT6som6918dTEJWNt/j7u0S5TARg3ZFJ8569LWsGrL/qGQyclWpckKrxnVYSXDe3qE3tulu0fXF5EoFyJwyeJ5qnb8DB8r6vhy8ASE6u6pNH71oHOfxaF4YH4XrH3a9hmpyJCGM15JpBhtohwboLcGydUZLYYAq4QM8yIBt4h87dTfGCnLfV7UeeVWre3VF5jm0ug58C7qIRQAv8bsQRCHhgTGAAuZXqag1YUBQrl5vt/tIGvT6O0A/FnLt6NKjiybv2Ecliml/h7hyf62jkEyMIWr6fJ2SCKuRvXWfqtA8NcRq7SdxUDMuTPryOAqd/wDvOrJzJS2rQ9YNUOrEDf3HoQ9tH/+mwIliKG+lusdjxRcN+seAlXd1f0/fiSBDwXh+Osi5gSVGqiFUQQCmzig8NCoJDCckwGw380m79Lx8FX5vNrC4neNRsj2aD0BdJ3PQcwK2IXaxS6OoBBPNIUxFKre2YvNu9QVrXkCV6y/uqJOnBDywC9hS2w3f0IA9bwEpzKvf8Uv/IeJlzFPYD2v4bTiyQqH+53BVmRVlhYJZuzjQrffOh6eDZDEzbcbeRe35MyiYb8EoyWjoKnv8F6Zyk6cUGJgvQWlwU/AEY009Q4+vSEKthjF17ek3IqIXC4OEbBgmfFMyqG7UL/pf/WCTtbUk8IQVl7AsBRSaxIDilyp+1EgVZ9bui4+HQu8DcS3Fz8NvULIMu5cKCpxinn+4CbX9h6OzKbRbb0DkI4RbjhVBJiwLkZLje+ejTBlS8PpyOIi/Ylx2kYqVXt4/hFaYZidIOOkbNxu+xjOGbtha9sq88dbhxY7OGPk3OAhqyhoNAvp4kXQVWO3nmYZz7cakFj/KZdiHhJlQlcVwlH5Q9yF51I00ziDdWp17pAz+tbUxSjxm6hyS7dV5rl4ABXHVarv6MGOCN5syG4+51CigSw5QPrCvFE0i/u91zZzlFiW+seEwoRWDnBf6TUt9r8U3Jba6hhd+yfbBmU6kNydSoy30JcFYbWlU5zy8M0h6BJcPPvq/4F9+Ot0sr X-OriginatorOrg: wdc.com X-MS-Exchange-CrossTenant-Network-Message-Id: 3cefe86f-35d4-457c-ce73-08d981abf35b X-MS-Exchange-CrossTenant-AuthSource: CO6PR04MB7812.namprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 27 Sep 2021 11:42:57.5192 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: b61c8803-16f3-4c35-9b17-6f65f441df86 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: X6eT9shcnNlvzdZccSAgMYNO75K7kJ38GFBKpFOGBGFcRU/eM+zWv9Eei/BNoJ3FSBlTTh80j9/xTDHxs9Ncew== X-MS-Exchange-Transport-CrossTenantHeadersStamped: CO6PR04MB7841 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org This patch implements kvm_cpu__ Guest/VM VCPU arch functions. These functions mostly deal with: 1. VCPU allocation and initialization 2. VCPU reset 3. VCPU show/dump code 4. VCPU show/dump registers We also save RISC-V ISA, XLEN, and TIMEBASE frequency for each VCPU so that it can be later used for generating Guest/VM FDT. Signed-off-by: Atish Patra Signed-off-by: Anup Patel --- riscv/include/kvm/kvm-cpu-arch.h | 4 + riscv/kvm-cpu.c | 393 ++++++++++++++++++++++++++++++- 2 files changed, 390 insertions(+), 7 deletions(-) diff --git a/riscv/include/kvm/kvm-cpu-arch.h b/riscv/include/kvm/kvm-cpu-arch.h index ae6ae0a..78fcd01 100644 --- a/riscv/include/kvm/kvm-cpu-arch.h +++ b/riscv/include/kvm/kvm-cpu-arch.h @@ -12,6 +12,10 @@ struct kvm_cpu { unsigned long cpu_id; + unsigned long riscv_xlen; + unsigned long riscv_isa; + unsigned long riscv_timebase; + struct kvm *kvm; int vcpu_fd; struct kvm_run *kvm_run; diff --git a/riscv/kvm-cpu.c b/riscv/kvm-cpu.c index e4b8fa5..8adaddd 100644 --- a/riscv/kvm-cpu.c +++ b/riscv/kvm-cpu.c @@ -17,10 +17,88 @@ int kvm_cpu__get_debug_fd(void) return debug_fd; } +static __u64 __kvm_reg_id(__u64 type, __u64 idx, __u64 size) +{ + return KVM_REG_RISCV | type | idx | size; +} + +#if __riscv_xlen == 64 +#define KVM_REG_SIZE_ULONG KVM_REG_SIZE_U64 +#else +#define KVM_REG_SIZE_ULONG KVM_REG_SIZE_U32 +#endif + +#define RISCV_CONFIG_REG(name) __kvm_reg_id(KVM_REG_RISCV_CONFIG, \ + KVM_REG_RISCV_CONFIG_REG(name), \ + KVM_REG_SIZE_ULONG) + +#define RISCV_CORE_REG(name) __kvm_reg_id(KVM_REG_RISCV_CORE, \ + KVM_REG_RISCV_CORE_REG(name), \ + KVM_REG_SIZE_ULONG) + +#define RISCV_CSR_REG(name) __kvm_reg_id(KVM_REG_RISCV_CSR, \ + KVM_REG_RISCV_CSR_REG(name), \ + KVM_REG_SIZE_ULONG) + +#define RISCV_TIMER_REG(name) __kvm_reg_id(KVM_REG_RISCV_TIMER, \ + KVM_REG_RISCV_TIMER_REG(name), \ + KVM_REG_SIZE_U64) + struct kvm_cpu *kvm_cpu__arch_init(struct kvm *kvm, unsigned long cpu_id) { - /* TODO: */ - return NULL; + struct kvm_cpu *vcpu; + u64 timebase = 0; + unsigned long isa = 0; + int coalesced_offset, mmap_size; + struct kvm_one_reg reg; + + vcpu = calloc(1, sizeof(struct kvm_cpu)); + if (!vcpu) + return NULL; + + vcpu->vcpu_fd = ioctl(kvm->vm_fd, KVM_CREATE_VCPU, cpu_id); + if (vcpu->vcpu_fd < 0) + die_perror("KVM_CREATE_VCPU ioctl"); + + reg.id = RISCV_CONFIG_REG(isa); + reg.addr = (unsigned long)&isa; + if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) + die("KVM_GET_ONE_REG failed (config.isa)"); + + reg.id = RISCV_TIMER_REG(frequency); + reg.addr = (unsigned long)&timebase; + if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) + die("KVM_GET_ONE_REG failed (timer.frequency)"); + + mmap_size = ioctl(kvm->sys_fd, KVM_GET_VCPU_MMAP_SIZE, 0); + if (mmap_size < 0) + die_perror("KVM_GET_VCPU_MMAP_SIZE ioctl"); + + vcpu->kvm_run = mmap(NULL, mmap_size, PROT_RW, MAP_SHARED, + vcpu->vcpu_fd, 0); + if (vcpu->kvm_run == MAP_FAILED) + die("unable to mmap vcpu fd"); + + coalesced_offset = ioctl(kvm->sys_fd, KVM_CHECK_EXTENSION, + KVM_CAP_COALESCED_MMIO); + if (coalesced_offset) + vcpu->ring = (void *)vcpu->kvm_run + + (coalesced_offset * PAGE_SIZE); + + reg.id = RISCV_CONFIG_REG(isa); + reg.addr = (unsigned long)&isa; + if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, ®) < 0) + die("KVM_SET_ONE_REG failed (config.isa)"); + + /* Populate the vcpu structure. */ + vcpu->kvm = kvm; + vcpu->cpu_id = cpu_id; + vcpu->riscv_isa = isa; + vcpu->riscv_xlen = __riscv_xlen; + vcpu->riscv_timebase = timebase; + vcpu->is_running = true; + + return vcpu; } void kvm_cpu__arch_nmi(struct kvm_cpu *cpu) @@ -29,7 +107,7 @@ void kvm_cpu__arch_nmi(struct kvm_cpu *cpu) void kvm_cpu__delete(struct kvm_cpu *vcpu) { - /* TODO: */ + free(vcpu); } bool kvm_cpu__handle_exit(struct kvm_cpu *vcpu) @@ -40,12 +118,43 @@ bool kvm_cpu__handle_exit(struct kvm_cpu *vcpu) void kvm_cpu__show_page_tables(struct kvm_cpu *vcpu) { - /* TODO: */ } void kvm_cpu__reset_vcpu(struct kvm_cpu *vcpu) { - /* TODO: */ + struct kvm *kvm = vcpu->kvm; + struct kvm_mp_state mp_state; + struct kvm_one_reg reg; + unsigned long data; + + if (ioctl(vcpu->vcpu_fd, KVM_GET_MP_STATE, &mp_state) < 0) + die_perror("KVM_GET_MP_STATE failed"); + + /* + * If MP state is stopped then it means Linux KVM RISC-V emulates + * SBI v0.2 (or higher) with HART power managment and give VCPU + * will power-up at boot-time by boot VCPU. For such VCPU, we + * don't update PC, A0 and A1 here. + */ + if (mp_state.mp_state == KVM_MP_STATE_STOPPED) + return; + + reg.addr = (unsigned long)&data; + + data = kvm->arch.kern_guest_start; + reg.id = RISCV_CORE_REG(regs.pc); + if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, ®) < 0) + die_perror("KVM_SET_ONE_REG failed (pc)"); + + data = vcpu->cpu_id; + reg.id = RISCV_CORE_REG(regs.a0); + if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, ®) < 0) + die_perror("KVM_SET_ONE_REG failed (a0)"); + + data = kvm->arch.dtb_guest_start; + reg.id = RISCV_CORE_REG(regs.a1); + if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, ®) < 0) + die_perror("KVM_SET_ONE_REG failed (a1)"); } int kvm_cpu__get_endianness(struct kvm_cpu *vcpu) @@ -55,10 +164,280 @@ int kvm_cpu__get_endianness(struct kvm_cpu *vcpu) void kvm_cpu__show_code(struct kvm_cpu *vcpu) { - /* TODO: */ + struct kvm_one_reg reg; + unsigned long data; + int debug_fd = kvm_cpu__get_debug_fd(); + + reg.addr = (unsigned long)&data; + + dprintf(debug_fd, "\n*PC:\n"); + reg.id = RISCV_CORE_REG(regs.pc); + if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) + die("KVM_GET_ONE_REG failed (show_code @ PC)"); + + kvm__dump_mem(vcpu->kvm, data, 32, debug_fd); + + dprintf(debug_fd, "\n*RA:\n"); + reg.id = RISCV_CORE_REG(regs.ra); + if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) + die("KVM_GET_ONE_REG failed (show_code @ RA)"); + + kvm__dump_mem(vcpu->kvm, data, 32, debug_fd); +} + +static void kvm_cpu__show_csrs(struct kvm_cpu *vcpu) +{ + struct kvm_one_reg reg; + struct kvm_riscv_csr csr; + unsigned long data; + int debug_fd = kvm_cpu__get_debug_fd(); + + reg.addr = (unsigned long)&data; + dprintf(debug_fd, "\n Control Status Registers:\n"); + dprintf(debug_fd, " ------------------------\n"); + + reg.id = RISCV_CSR_REG(sstatus); + if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) + die("KVM_GET_ONE_REG failed (sstatus)"); + csr.sstatus = data; + + reg.id = RISCV_CSR_REG(sie); + if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) + die("KVM_GET_ONE_REG failed (sie)"); + csr.sie = data; + + reg.id = RISCV_CSR_REG(stvec); + if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) + die("KVM_GET_ONE_REG failed (stvec)"); + csr.stvec = data; + + reg.id = RISCV_CSR_REG(sip); + if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) + die("KVM_GET_ONE_REG failed (sip)"); + csr.sip = data; + + reg.id = RISCV_CSR_REG(satp); + if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) + die("KVM_GET_ONE_REG failed (satp)"); + csr.satp = data; + + reg.id = RISCV_CSR_REG(stval); + if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) + die("KVM_GET_ONE_REG failed (stval)"); + csr.stval = data; + + reg.id = RISCV_CSR_REG(scause); + if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) + die("KVM_GET_ONE_REG failed (SCAUSE)"); + csr.scause = data; + + reg.id = RISCV_CSR_REG(sscratch); + if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) + die("KVM_GET_ONE_REG failed (sscartch)"); + csr.sscratch = data; + dprintf(debug_fd, " SSTATUS: 0x%016lx\n", csr.sstatus); + dprintf(debug_fd, " SIE: 0x%016lx\n", csr.sie); + dprintf(debug_fd, " STVEC: 0x%016lx\n", csr.stvec); + dprintf(debug_fd, " SIP: 0x%016lx\n", csr.sip); + dprintf(debug_fd, " SATP: 0x%016lx\n", csr.satp); + dprintf(debug_fd, " STVAL: 0x%016lx\n", csr.stval); + dprintf(debug_fd, " SCAUSE: 0x%016lx\n", csr.scause); + dprintf(debug_fd, " SSCRATCH: 0x%016lx\n", csr.sscratch); } void kvm_cpu__show_registers(struct kvm_cpu *vcpu) { - /* TODO: */ + struct kvm_one_reg reg; + unsigned long data; + int debug_fd = kvm_cpu__get_debug_fd(); + struct kvm_riscv_core core; + + reg.addr = (unsigned long)&data; + + reg.id = RISCV_CORE_REG(mode); + if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) + die("KVM_GET_ONE_REG failed (mode)"); + core.mode = data; + + reg.id = RISCV_CORE_REG(regs.pc); + if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) + die("KVM_GET_ONE_REG failed (pc)"); + core.regs.pc = data; + + reg.id = RISCV_CORE_REG(regs.ra); + if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) + die("KVM_GET_ONE_REG failed (ra)"); + core.regs.ra = data; + + reg.id = RISCV_CORE_REG(regs.sp); + if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) + die("KVM_GET_ONE_REG failed (sp)"); + core.regs.sp = data; + + reg.id = RISCV_CORE_REG(regs.gp); + if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) + die("KVM_GET_ONE_REG failed (gp)"); + core.regs.gp = data; + + reg.id = RISCV_CORE_REG(regs.tp); + if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) + die("KVM_GET_ONE_REG failed (tp)"); + core.regs.tp = data; + + reg.id = RISCV_CORE_REG(regs.t0); + if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) + die("KVM_GET_ONE_REG failed (t0)"); + core.regs.t0 = data; + + reg.id = RISCV_CORE_REG(regs.t1); + if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) + die("KVM_GET_ONE_REG failed (t1)"); + core.regs.t1 = data; + + reg.id = RISCV_CORE_REG(regs.t2); + if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) + die("KVM_GET_ONE_REG failed (t2)"); + core.regs.t2 = data; + + reg.id = RISCV_CORE_REG(regs.s0); + if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) + die("KVM_GET_ONE_REG failed (s0)"); + core.regs.s0 = data; + + reg.id = RISCV_CORE_REG(regs.s1); + if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) + die("KVM_GET_ONE_REG failed (s1)"); + core.regs.s1 = data; + + reg.id = RISCV_CORE_REG(regs.a0); + if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) + die("KVM_GET_ONE_REG failed (a0)"); + core.regs.a0 = data; + + reg.id = RISCV_CORE_REG(regs.a1); + if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) + die("KVM_GET_ONE_REG failed (a1)"); + core.regs.a1 = data; + + reg.id = RISCV_CORE_REG(regs.a2); + if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) + die("KVM_GET_ONE_REG failed (a2)"); + core.regs.a2 = data; + + reg.id = RISCV_CORE_REG(regs.a3); + if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) + die("KVM_GET_ONE_REG failed (a3)"); + core.regs.a3 = data; + + reg.id = RISCV_CORE_REG(regs.a4); + if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) + die("KVM_GET_ONE_REG failed (a4)"); + core.regs.a4 = data; + + reg.id = RISCV_CORE_REG(regs.a5); + if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) + die("KVM_GET_ONE_REG failed (a5)"); + core.regs.a5 = data; + + reg.id = RISCV_CORE_REG(regs.a6); + if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) + die("KVM_GET_ONE_REG failed (a6)"); + core.regs.a6 = data; + + reg.id = RISCV_CORE_REG(regs.a7); + if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) + die("KVM_GET_ONE_REG failed (a7)"); + core.regs.a7 = data; + + reg.id = RISCV_CORE_REG(regs.s2); + if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) + die("KVM_GET_ONE_REG failed (s2)"); + core.regs.s2 = data; + + reg.id = RISCV_CORE_REG(regs.s3); + if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) + die("KVM_GET_ONE_REG failed (s3)"); + core.regs.s3 = data; + + reg.id = RISCV_CORE_REG(regs.s4); + if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) + die("KVM_GET_ONE_REG failed (s4)"); + core.regs.s4 = data; + + reg.id = RISCV_CORE_REG(regs.s5); + if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) + die("KVM_GET_ONE_REG failed (s5)"); + core.regs.s5 = data; + + reg.id = RISCV_CORE_REG(regs.s6); + if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) + die("KVM_GET_ONE_REG failed (s6)"); + core.regs.s6 = data; + + reg.id = RISCV_CORE_REG(regs.s7); + if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) + die("KVM_GET_ONE_REG failed (s7)"); + core.regs.s7 = data; + + reg.id = RISCV_CORE_REG(regs.s8); + if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) + die("KVM_GET_ONE_REG failed (s8)"); + core.regs.s8 = data; + + reg.id = RISCV_CORE_REG(regs.s9); + if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) + die("KVM_GET_ONE_REG failed (s9)"); + core.regs.s9 = data; + + reg.id = RISCV_CORE_REG(regs.s10); + if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) + die("KVM_GET_ONE_REG failed (s10)"); + core.regs.s10 = data; + + reg.id = RISCV_CORE_REG(regs.s11); + if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) + die("KVM_GET_ONE_REG failed (s11)"); + core.regs.s11 = data; + + reg.id = RISCV_CORE_REG(regs.t3); + if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) + die("KVM_GET_ONE_REG failed (t3)"); + core.regs.t3 = data; + + reg.id = RISCV_CORE_REG(regs.t4); + if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) + die("KVM_GET_ONE_REG failed (t4)"); + core.regs.t4 = data; + + reg.id = RISCV_CORE_REG(regs.t5); + if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) + die("KVM_GET_ONE_REG failed (t5)"); + core.regs.t5 = data; + + reg.id = RISCV_CORE_REG(regs.t6); + if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) + die("KVM_GET_ONE_REG failed (t6)"); + core.regs.t6 = data; + + dprintf(debug_fd, "\n General Purpose Registers:\n"); + dprintf(debug_fd, " -------------------------\n"); + dprintf(debug_fd, " MODE: 0x%lx\n", data); + dprintf(debug_fd, " PC: 0x%016lx RA: 0x%016lx SP: 0x%016lx GP: 0x%016lx\n", + core.regs.pc, core.regs.ra, core.regs.sp, core.regs.gp); + dprintf(debug_fd, " TP: 0x%016lx T0: 0x%016lx T1: 0x%016lx T2: 0x%016lx\n", + core.regs.tp, core.regs.t0, core.regs.t1, core.regs.t2); + dprintf(debug_fd, " S0: 0x%016lx S1: 0x%016lx A0: 0x%016lx A1: 0x%016lx\n", + core.regs.s0, core.regs.s1, core.regs.a0, core.regs.a1); + dprintf(debug_fd, " A2: 0x%016lx A3: 0x%016lx A4: 0x%016lx A5: 0x%016lx\n", + core.regs.a2, core.regs.a3, core.regs.a4, core.regs.a5); + dprintf(debug_fd, " A6: 0x%016lx A7: 0x%016lx S2: 0x%016lx S3: 0x%016lx\n", + core.regs.a6, core.regs.a7, core.regs.s2, core.regs.s3); + dprintf(debug_fd, " S4: 0x%016lx S5: 0x%016lx S6: 0x%016lx S7: 0x%016lx\n", + core.regs.s4, core.regs.s5, core.regs.s6, core.regs.s7); + dprintf(debug_fd, " S8: 0x%016lx S9: 0x%016lx S10: 0x%016lx S11: 0x%016lx\n", + core.regs.s8, core.regs.s9, core.regs.s10, core.regs.s11); + dprintf(debug_fd, " T3: 0x%016lx T4: 0x%016lx T5: 0x%016lx T6: 0x%016lx\n", + core.regs.t3, core.regs.t4, core.regs.t5, core.regs.t6); + + kvm_cpu__show_csrs(vcpu); } From patchwork Mon Sep 27 11:42:24 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anup Patel X-Patchwork-Id: 12519641 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0702BC433F5 for ; Mon, 27 Sep 2021 11:43:19 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E5FA360F4B for ; Mon, 27 Sep 2021 11:43:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234237AbhI0Loy (ORCPT ); Mon, 27 Sep 2021 07:44:54 -0400 Received: from esa6.hgst.iphmx.com ([216.71.154.45]:36556 "EHLO esa6.hgst.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234042AbhI0Lol (ORCPT ); Mon, 27 Sep 2021 07:44:41 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=wdc.com; i=@wdc.com; q=dns/txt; s=dkim.wdc.com; t=1632742984; x=1664278984; h=from:to:cc:subject:date:message-id:in-reply-to: references:content-transfer-encoding:mime-version; bh=TUSHSGKgY513FTY4kvyF1wBc/J5UHDuWpEEce7W2SYY=; b=a0XNY9uzGjcoT4NYf/Tynf59CvKvX1MlF+OKzQsbG03T2lecwmg8ged2 A/hPjkEqLH4eal/2frcOzlrNcn3LCuEhPESW8FxE9DpCacJqcgaFgBd9Y ecPe6qqI/ikQD+hATZjj7QC998zalWQsef7BxYzEyMW83ZLJFBfjFARwG byosmGRRa2fj9ZB65wKfvY3mvxU2Acop66WmLzjaxPCF4lZ+v7Oedad/x 7vHd1wOg/MlQxmBFpBCs2Qnz8Unhnbyhyy5/tTamwLVVJxpJVNbGZDxY9 db7yKM/wVEgxBsYxifc6nEK3Fg9yc/y7GtDHPqFgi4NkF4WXchukgkh9o A==; X-IronPort-AV: E=Sophos;i="5.85,326,1624291200"; d="scan'208";a="181673173" Received: from mail-bn8nam08lp2045.outbound.protection.outlook.com (HELO NAM04-BN8-obe.outbound.protection.outlook.com) ([104.47.74.45]) by ob1.hgst.iphmx.com with ESMTP; 27 Sep 2021 19:43:03 +0800 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=oVqvSgnAtoR1+6o2g+hKou3LVC8pKvkSp6t7hcz7Zrt0nP3sSXoXHFBX7j7wMPpba4QYOt5n99153I+J0ield/WVZdxVfIL95ygkSZslpEOZARrB8zcggeaf9TLBHbDf7X1YrXB4wfDF8gBJcobmXlrFnYqT2IWgdlG7v0mH9KtPRxsaw9EHB1ImkLrx8RHc68oXrfaqQe7ThvAMb9dipyxQs2g8Q0sFeaXMjpOgu4JTl8DCfPVp/HKKVLEeEBYHkeP+gFH8doLiYeRXldUFXpOZM3TRn9+MptChZzAwV7nM+NGumLdSrOod3njG8xlgn6Di6F6bmoKgg57FYEyXLg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=IUJLc6HbV5HqzPXnor3+5McW1YZUUpMFi+omPeRoeFk=; b=aa4lO/ZQJw+msM/G7yCeFPRmhUDnMim6wOjfRpSCiHZKu6djwAq/RjPi5R3tCBCamEchy15/GMRH1jMvFOY8Ee2aWojhzBYRrPzOxYf8qyB/nhC5vipcoZP73ER3Fe8lzNeey4rN3F59XjumtlRDaDHMzQfsRTHSnJGQXwr4FPc/Z/fGoXij6umvCtx38ZI7LL0AtpLD1QXx0BryvwM4vKWpODPHD+7kNf31QKL7mbFbXd460guU7SQqWKcy86rJgL3nYaAmK66Vs01n3Nxnm2c4iEDHWOVWx11FEL7Zfu1FSScEnEULK155uzRm14lPdGokh5HS5xYKEJvn7tYdfg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=wdc.com; dmarc=pass action=none header.from=wdc.com; dkim=pass header.d=wdc.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sharedspace.onmicrosoft.com; s=selector2-sharedspace-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=IUJLc6HbV5HqzPXnor3+5McW1YZUUpMFi+omPeRoeFk=; b=OP7iCN30GMUo/l7GETA96nei4dayT9L/MvitWZ+S4nmUU2mhH7n3JYxTEqi10Z9YeiJ984Z2+PVTkLnXXSxx3wr1wAAxrNn+HME7CMwNUzG5TyecjKkgXvFTj09bocBmoQpCqvLUUY++20/0yCOr8M4AQoSqLgl8IZ6QQDFOTqM= Authentication-Results: kernel.org; dkim=none (message not signed) header.d=none;kernel.org; dmarc=none action=none header.from=wdc.com; Received: from CO6PR04MB7812.namprd04.prod.outlook.com (2603:10b6:303:138::6) by CO6PR04MB7841.namprd04.prod.outlook.com (2603:10b6:5:358::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4544.13; Mon, 27 Sep 2021 11:43:00 +0000 Received: from CO6PR04MB7812.namprd04.prod.outlook.com ([fe80::6830:650b:8265:af0b]) by CO6PR04MB7812.namprd04.prod.outlook.com ([fe80::6830:650b:8265:af0b%6]) with mapi id 15.20.4544.021; Mon, 27 Sep 2021 11:43:00 +0000 From: Anup Patel To: Will Deacon Cc: Paolo Bonzini , Atish Patra , Alistair Francis , Anup Patel , kvm@vger.kernel.org, kvm-riscv@lists.infradead.org, Anup Patel , Vincent Chen Subject: [PATCH v9 5/8] riscv: Add PLIC device emulation Date: Mon, 27 Sep 2021 17:12:24 +0530 Message-Id: <20210927114227.1089403-6-anup.patel@wdc.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210927114227.1089403-1-anup.patel@wdc.com> References: <20210927114227.1089403-1-anup.patel@wdc.com> X-ClientProxiedBy: MA1PR01CA0173.INDPRD01.PROD.OUTLOOK.COM (2603:1096:a01:d::14) To CO6PR04MB7812.namprd04.prod.outlook.com (2603:10b6:303:138::6) MIME-Version: 1.0 Received: from wdc.com (122.179.75.205) by MA1PR01CA0173.INDPRD01.PROD.OUTLOOK.COM (2603:1096:a01:d::14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4544.14 via Frontend Transport; Mon, 27 Sep 2021 11:42:57 +0000 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 085f3525-ea40-4dc6-5010-08d981abf51f X-MS-TrafficTypeDiagnostic: CO6PR04MB7841: X-MS-Exchange-Transport-Forked: True X-Microsoft-Antispam-PRVS: WDCIPOUTBOUND: EOP-TRUE X-MS-Oob-TLC-OOBClassifiers: OLM:5236; X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: 7gb1cM+JRwCSLt8U/bOCoSX6lL+Gc+0+Pn8RUPvQqhG7GwnaCmGz3UNbrJAkor4NECO7pdy2vmILsaYB29API87i27PxENqNyCAqP4GjhSXfJHuoOiqEiFjf/3bDCPf2CAZq7vke3sYT+InJVuNyyA1hzTcEEvh+bkhNZauix7DtsAMNjt1jKyhtSsdrGUDZ6AA01AxGG9/Ur22vgI1Rs/8Vlq57Fw/Al5IzWEqFGcUuxso/NBimwyvr/Uc/cRAJ1h3W09Gg7wywGRpV2V2WCFgy1VSGt+EbCTDsY821ebD+CGI7Hxd8EiIp7n/6PvVQ14PH2WrjxrX/O9sfixBJPUr77V3rmGm9RGbZQ8viWCGHn+ekB7hs3SR2yImYyFoUEBxOPAwBpNWmXuF1yJjgnPGj1Wsfl3YOnMUGqwUZR9vUu5kvFxyc9Yxp3MPOHM7LG7aWt+NM7VTzb4AloFlpwRInhdYcwPaarw3GNgbwlaKwQygVTngp5lijdAnkwfsiDHPUgjTehBf25wDJHhrqluQ3YX2R7eNrofmKzKdV0QZ3wDm+Jr1mj3fKjRpe+qMXH86+YsBj7XD9TsHRL10n57Ox0FMR56FitSEglyQ1gggwhn1gO6+8nrLk7sCCMqEJmfk1bTlKMgRyB5Mb+ZiNPN2OGdj9iUKnQI128cyvG4IWuizYz40DDKiIt94sLRHM X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:CO6PR04MB7812.namprd04.prod.outlook.com;PTR:;CAT:NONE;SFS:(4636009)(366004)(54906003)(316002)(5660300002)(1076003)(66556008)(83380400001)(30864003)(66946007)(66476007)(36756003)(38100700002)(38350700002)(55016002)(86362001)(508600001)(6916009)(44832011)(8886007)(6666004)(2906002)(8676002)(956004)(2616005)(7696005)(8936002)(4326008)(26005)(52116002)(186003);DIR:OUT;SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: Dv8sP+Y2varedHA6nEUdrSLzB16KY3GlUNcgR2fnIS9mMI5fmqCg72Kki7jFgebLQpX+kjMibsKotJXh47CxDhtiC5hIFUl0fy52ihfLBQs1TZccFb15n+mhBcHLnDes8edq4CTM/Yu87+jLXPLCEe3/ofYBTRUjpebee/nx4R5/tA+UagRQFQPkoHlLJfJ5UnFE+srxakIDbGeOX6arI40WeLy6IjpY5eb+7NYMb3OJszsR4zuic/sXj4E1kd21a+TPSBRDb2y11u8ppF3m16fcpz2U/QuqkDpDYm6U8NFNLBVn3MbRcVCFricOyN4r7/1vv+qokX7RPLfVzHJTZqlrBAcS0ouur2QoQb/5YL6DkUIExkbksh0hmidl9uVOhiQTR854H5t0d5otAEUzp0bW2yfjcdA+LfZLnPOUjPuJQACvFXdRTTe+DDCHkZz5iJYbNq6/8I65KCSCxyVHj+1DKEp5BXC463hVk9+Y04XOYjFeQOUDEqzUYoytFG+LkXhIZk1GJzQyldqN10eyz6jZbcq5p1Hl3sns1S8NFHXvNe/XvucikJUPuIcB0fJxRTtYmg6NH03wFZsIXwZOlIyEassU8QppeJFwQoWLZNFB4p1st/T+V4PS7KRB5TIDUs57oBFPlWDEhkQIRLBioAaLYoNFbxNRIM5neQWpxEFm+Xf7PeK20l7vf8brnJzNaZycy7G7jOVWnX8KcpSdgZpUHV14L7Y1tCpvl32P3TYiQ73Vzb5bx52pCAKHGP/Lisi84rO6GMT6FqeSXflFpQOgXKjQ96w3jiVL/iS7cF3AN4Nrd8R+6egqw40TF/btI8e3dDRGUTzZ+MRWLAglLLlNf4TPi+7h+n993bnkhHFV2ebLc7tUkNXGxPFt3csC7ta+Y1eicBUeAvqyAbRaDXiFyf2bhSmBv3rukYaDlQTgpNCMtmI30Em2DFQUZSuRfojjcaH02yWe0lcoIzv2MiAe+cWHFssQERSP7kpU8ChKK4gPfP7w81sYdRJRtCfDREi5LjUZ/p+Uk4QZWcLWLQF3JpYH1c8yIybTlA4up5rzvdDNhR6Yh8/D19pLdZ0j8tTSEc2UG1CF/DVHNyx6546tySx2OHxdiJxyYpJKMRR+zZ+ttMp7qFSNGi6onMilZ8FIJHkbvNpxqpx0PFzXyMDoDR3LNUUxjNbbZDhD1/x1HskEc1shmxDMNqXdi1rYwv6ikUfdVravLPV7oV/rrJWb+FDRCNByUHFGJCssnpDsZIX3PyywDwq9sZ/dOfBoVGLr+jqvTKGLXdUjIDx+yxTjensudypX2SSV4LFT0vYni6qEnqEADYcH5LRsWk3F X-OriginatorOrg: wdc.com X-MS-Exchange-CrossTenant-Network-Message-Id: 085f3525-ea40-4dc6-5010-08d981abf51f X-MS-Exchange-CrossTenant-AuthSource: CO6PR04MB7812.namprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 27 Sep 2021 11:43:00.2950 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: b61c8803-16f3-4c35-9b17-6f65f441df86 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: Ci9g3UhzOYV5r6waGaHA2vA+RO4DicRsprdNWHedoplw+HxXrjZ1HqOPoGd3x7rKjkhLMZErNl7kv+ox+wsQuw== X-MS-Exchange-Transport-CrossTenantHeadersStamped: CO6PR04MB7841 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org The PLIC (platform level interrupt controller) manages peripheral interrupts in RISC-V world. The per-CPU interrupts are managed using CPU CSRs hence virtualized in-kernel by KVM RISC-V. This patch adds PLIC device emulation for KVMTOOL RISC-V. Signed-off-by: Vincent Chen [For PLIC context CLAIM register emulation] Signed-off-by: Anup Patel --- Makefile | 1 + riscv/include/kvm/kvm-arch.h | 2 + riscv/irq.c | 4 +- riscv/plic.c | 518 +++++++++++++++++++++++++++++++++++ 4 files changed, 523 insertions(+), 2 deletions(-) create mode 100644 riscv/plic.c diff --git a/Makefile b/Makefile index 817f45c..eacf766 100644 --- a/Makefile +++ b/Makefile @@ -203,6 +203,7 @@ ifeq ($(ARCH),riscv) OBJS += riscv/irq.o OBJS += riscv/kvm.o OBJS += riscv/kvm-cpu.o + OBJS += riscv/plic.o ifeq ($(RISCV_XLEN),32) CFLAGS += -mabi=ilp32d -march=rv32gc endif diff --git a/riscv/include/kvm/kvm-arch.h b/riscv/include/kvm/kvm-arch.h index 529d5b3..9face96 100644 --- a/riscv/include/kvm/kvm-arch.h +++ b/riscv/include/kvm/kvm-arch.h @@ -78,4 +78,6 @@ static inline bool riscv_addr_in_ioport_region(u64 phys_addr) enum irq_type; +void plic__irq_trig(struct kvm *kvm, int irq, int level, bool edge); + #endif /* KVM__KVM_ARCH_H */ diff --git a/riscv/irq.c b/riscv/irq.c index 8e605ef..78a582d 100644 --- a/riscv/irq.c +++ b/riscv/irq.c @@ -4,10 +4,10 @@ void kvm__irq_line(struct kvm *kvm, int irq, int level) { - /* TODO: */ + plic__irq_trig(kvm, irq, level, false); } void kvm__irq_trigger(struct kvm *kvm, int irq) { - /* TODO: */ + plic__irq_trig(kvm, irq, 1, true); } diff --git a/riscv/plic.c b/riscv/plic.c new file mode 100644 index 0000000..d71226e --- /dev/null +++ b/riscv/plic.c @@ -0,0 +1,518 @@ + +#include "kvm/devices.h" +#include "kvm/ioeventfd.h" +#include "kvm/ioport.h" +#include "kvm/kvm.h" +#include "kvm/kvm-cpu.h" +#include "kvm/irq.h" +#include "kvm/mutex.h" + +#include +#include +#include +#include + +/* + * From the RISC-V Privlidged Spec v1.10: + * + * Global interrupt sources are assigned small unsigned integer identifiers, + * beginning at the value 1. An interrupt ID of 0 is reserved to mean no + * interrupt. Interrupt identifiers are also used to break ties when two or + * more interrupt sources have the same assigned priority. Smaller values of + * interrupt ID take precedence over larger values of interrupt ID. + * + * While the RISC-V supervisor spec doesn't define the maximum number of + * devices supported by the PLIC, the largest number supported by devices + * marked as 'riscv,plic0' (which is the only device type this driver supports, + * and is the only extant PLIC as of now) is 1024. As mentioned above, device + * 0 is defined to be non-existant so this device really only supports 1023 + * devices. + */ + +#define MAX_DEVICES 1024 +#define MAX_CONTEXTS 15872 + +/* + * The PLIC consists of memory-mapped control registers, with a memory map as + * follows: + * + * base + 0x000000: Reserved (interrupt source 0 does not exist) + * base + 0x000004: Interrupt source 1 priority + * base + 0x000008: Interrupt source 2 priority + * ... + * base + 0x000FFC: Interrupt source 1023 priority + * base + 0x001000: Pending 0 + * base + 0x001FFF: Pending + * base + 0x002000: Enable bits for sources 0-31 on context 0 + * base + 0x002004: Enable bits for sources 32-63 on context 0 + * ... + * base + 0x0020FC: Enable bits for sources 992-1023 on context 0 + * base + 0x002080: Enable bits for sources 0-31 on context 1 + * ... + * base + 0x002100: Enable bits for sources 0-31 on context 2 + * ... + * base + 0x1F1F80: Enable bits for sources 992-1023 on context 15871 + * base + 0x1F1F84: Reserved + * ... (higher context IDs would fit here, but wouldn't fit + * inside the per-context priority vector) + * base + 0x1FFFFC: Reserved + * base + 0x200000: Priority threshold for context 0 + * base + 0x200004: Claim/complete for context 0 + * base + 0x200008: Reserved + * ... + * base + 0x200FFC: Reserved + * base + 0x201000: Priority threshold for context 1 + * base + 0x201004: Claim/complete for context 1 + * ... + * base + 0xFFE000: Priority threshold for context 15871 + * base + 0xFFE004: Claim/complete for context 15871 + * base + 0xFFE008: Reserved + * ... + * base + 0xFFFFFC: Reserved + */ + +/* Each interrupt source has a priority register associated with it. */ +#define PRIORITY_BASE 0 +#define PRIORITY_PER_ID 4 + +/* + * Each hart context has a vector of interupt enable bits associated with it. + * There's one bit for each interrupt source. + */ +#define ENABLE_BASE 0x2000 +#define ENABLE_PER_HART 0x80 + +/* + * Each hart context has a set of control registers associated with it. Right + * now there's only two: a source priority threshold over which the hart will + * take an interrupt, and a register to claim interrupts. + */ +#define CONTEXT_BASE 0x200000 +#define CONTEXT_PER_HART 0x1000 +#define CONTEXT_THRESHOLD 0 +#define CONTEXT_CLAIM 4 + +#define REG_SIZE 0x1000000 + +struct plic_state; + +struct plic_context { + /* State to which this belongs */ + struct plic_state *s; + + /* Static Configuration */ + u32 num; + struct kvm_cpu *vcpu; + + /* Local IRQ state */ + struct mutex irq_lock; + u8 irq_priority_threshold; + u32 irq_enable[MAX_DEVICES/32]; + u32 irq_pending[MAX_DEVICES/32]; + u8 irq_pending_priority[MAX_DEVICES]; + u32 irq_claimed[MAX_DEVICES/32]; + u32 irq_autoclear[MAX_DEVICES/32]; +}; + +struct plic_state { + bool ready; + struct kvm *kvm; + struct device_header dev_hdr; + + /* Static Configuration */ + u32 num_irq; + u32 num_irq_word; + u32 max_prio; + + /* Context Array */ + u32 num_context; + struct plic_context *contexts; + + /* Global IRQ state */ + struct mutex irq_lock; + u8 irq_priority[MAX_DEVICES]; + u32 irq_level[MAX_DEVICES/32]; +}; + +static struct plic_state plic; + +/* Note: Must be called with c->irq_lock held */ +static u32 __plic_context_best_pending_irq(struct plic_state *s, + struct plic_context *c) +{ + u8 best_irq_prio = 0; + u32 i, j, irq, best_irq = 0; + + for (i = 0; i < s->num_irq_word; i++) { + if (!c->irq_pending[i]) + continue; + + for (j = 0; j < 32; j++) { + irq = i * 32 + j; + if ((s->num_irq <= irq) || + !(c->irq_pending[i] & (1 << j)) || + (c->irq_claimed[i] & (1 << j))) + continue; + + if (!best_irq || + (best_irq_prio < c->irq_pending_priority[irq])) { + best_irq = irq; + best_irq_prio = c->irq_pending_priority[irq]; + } + } + } + + return best_irq; +} + +/* Note: Must be called with c->irq_lock held */ +static void __plic_context_irq_update(struct plic_state *s, + struct plic_context *c) +{ + u32 best_irq = __plic_context_best_pending_irq(s, c); + u32 virq = (best_irq) ? KVM_INTERRUPT_SET : KVM_INTERRUPT_UNSET; + + if (ioctl(c->vcpu->vcpu_fd, KVM_INTERRUPT, &virq) < 0) + pr_warning("KVM_INTERRUPT failed"); +} + +/* Note: Must be called with c->irq_lock held */ +static u32 __plic_context_irq_claim(struct plic_state *s, + struct plic_context *c) +{ + u32 virq = KVM_INTERRUPT_UNSET; + u32 best_irq = __plic_context_best_pending_irq(s, c); + u32 best_irq_word = best_irq / 32; + u32 best_irq_mask = (1 << (best_irq % 32)); + + if (ioctl(c->vcpu->vcpu_fd, KVM_INTERRUPT, &virq) < 0) + pr_warning("KVM_INTERRUPT failed"); + + if (best_irq) { + if (c->irq_autoclear[best_irq_word] & best_irq_mask) { + c->irq_pending[best_irq_word] &= ~best_irq_mask; + c->irq_pending_priority[best_irq] = 0; + c->irq_claimed[best_irq_word] &= ~best_irq_mask; + c->irq_autoclear[best_irq_word] &= ~best_irq_mask; + } else + c->irq_claimed[best_irq_word] |= best_irq_mask; + } + + __plic_context_irq_update(s, c); + + return best_irq; +} + +void plic__irq_trig(struct kvm *kvm, int irq, int level, bool edge) +{ + bool irq_marked = false; + u8 i, irq_prio, irq_word; + u32 irq_mask; + struct plic_context *c = NULL; + struct plic_state *s = &plic; + + if (!s->ready) + return; + + if (irq <= 0 || s->num_irq <= (u32)irq) + goto done; + + mutex_lock(&s->irq_lock); + + irq_prio = s->irq_priority[irq]; + irq_word = irq / 32; + irq_mask = 1 << (irq % 32); + + if (level) + s->irq_level[irq_word] |= irq_mask; + else + s->irq_level[irq_word] &= ~irq_mask; + + /* + * Note: PLIC interrupts are level-triggered. As of now, + * there is no notion of edge-triggered interrupts. To + * handle this we auto-clear edge-triggered interrupts + * when PLIC context CLAIM register is read. + */ + for (i = 0; i < s->num_context; i++) { + c = &s->contexts[i]; + + mutex_lock(&c->irq_lock); + if (c->irq_enable[irq_word] & irq_mask) { + if (level) { + c->irq_pending[irq_word] |= irq_mask; + c->irq_pending_priority[irq] = irq_prio; + if (edge) + c->irq_autoclear[irq_word] |= irq_mask; + } else { + c->irq_pending[irq_word] &= ~irq_mask; + c->irq_pending_priority[irq] = 0; + c->irq_claimed[irq_word] &= ~irq_mask; + c->irq_autoclear[irq_word] &= ~irq_mask; + } + __plic_context_irq_update(s, c); + irq_marked = true; + } + mutex_unlock(&c->irq_lock); + + if (irq_marked) + break; + } + +done: + mutex_unlock(&s->irq_lock); +} + +static void plic__priority_read(struct plic_state *s, + u64 offset, void *data) +{ + u32 irq = (offset >> 2); + + if (irq == 0 || irq >= s->num_irq) + return; + + mutex_lock(&s->irq_lock); + ioport__write32(data, s->irq_priority[irq]); + mutex_unlock(&s->irq_lock); +} + +static void plic__priority_write(struct plic_state *s, + u64 offset, void *data) +{ + u32 val, irq = (offset >> 2); + + if (irq == 0 || irq >= s->num_irq) + return; + + mutex_lock(&s->irq_lock); + val = ioport__read32(data); + val &= ((1 << PRIORITY_PER_ID) - 1); + s->irq_priority[irq] = val; + mutex_unlock(&s->irq_lock); +} + +static void plic__context_enable_read(struct plic_state *s, + struct plic_context *c, + u64 offset, void *data) +{ + u32 irq_word = offset >> 2; + + if (s->num_irq_word < irq_word) + return; + + mutex_lock(&c->irq_lock); + ioport__write32(data, c->irq_enable[irq_word]); + mutex_unlock(&c->irq_lock); +} + +static void plic__context_enable_write(struct plic_state *s, + struct plic_context *c, + u64 offset, void *data) +{ + u8 irq_prio; + u32 i, irq, irq_mask; + u32 irq_word = offset >> 2; + u32 old_val, new_val, xor_val; + + if (s->num_irq_word < irq_word) + return; + + mutex_lock(&s->irq_lock); + + mutex_lock(&c->irq_lock); + + old_val = c->irq_enable[irq_word]; + new_val = ioport__read32(data); + + if (irq_word == 0) + new_val &= ~0x1; + + c->irq_enable[irq_word] = new_val; + + xor_val = old_val ^ new_val; + for (i = 0; i < 32; i++) { + irq = irq_word * 32 + i; + irq_mask = 1 << i; + irq_prio = s->irq_priority[irq]; + if (!(xor_val & irq_mask)) + continue; + if ((new_val & irq_mask) && + (s->irq_level[irq_word] & irq_mask)) { + c->irq_pending[irq_word] |= irq_mask; + c->irq_pending_priority[irq] = irq_prio; + } else if (!(new_val & irq_mask)) { + c->irq_pending[irq_word] &= ~irq_mask; + c->irq_pending_priority[irq] = 0; + c->irq_claimed[irq_word] &= ~irq_mask; + } + } + + __plic_context_irq_update(s, c); + + mutex_unlock(&c->irq_lock); + + mutex_unlock(&s->irq_lock); +} + +static void plic__context_read(struct plic_state *s, + struct plic_context *c, + u64 offset, void *data) +{ + mutex_lock(&c->irq_lock); + + switch (offset) { + case CONTEXT_THRESHOLD: + ioport__write32(data, c->irq_priority_threshold); + break; + case CONTEXT_CLAIM: + ioport__write32(data, __plic_context_irq_claim(s, c)); + break; + default: + break; + }; + + mutex_unlock(&c->irq_lock); +} + +static void plic__context_write(struct plic_state *s, + struct plic_context *c, + u64 offset, void *data) +{ + u32 val; + bool irq_update = false; + + mutex_lock(&c->irq_lock); + + switch (offset) { + case CONTEXT_THRESHOLD: + val = ioport__read32(data); + val &= ((1 << PRIORITY_PER_ID) - 1); + if (val <= s->max_prio) + c->irq_priority_threshold = val; + else + irq_update = true; + break; + case CONTEXT_CLAIM: + val = ioport__read32(data); + if (val < plic.num_irq) { + c->irq_claimed[val / 32] &= ~(1 << (val % 32)); + irq_update = true; + } + break; + default: + irq_update = true; + break; + }; + + if (irq_update) + __plic_context_irq_update(s, c); + + mutex_unlock(&c->irq_lock); +} + +static void plic__mmio_callback(struct kvm_cpu *vcpu, + u64 addr, u8 *data, u32 len, + u8 is_write, void *ptr) +{ + u32 cntx; + struct plic_state *s = ptr; + + if (len != 4) + die("plic: invalid len=%d", len); + + addr &= ~0x3; + addr -= RISCV_PLIC; + + if (is_write) { + if (PRIORITY_BASE <= addr && addr < ENABLE_BASE) { + plic__priority_write(s, addr, data); + } else if (ENABLE_BASE <= addr && addr < CONTEXT_BASE) { + cntx = (addr - ENABLE_BASE) / ENABLE_PER_HART; + addr -= cntx * ENABLE_PER_HART + ENABLE_BASE; + if (cntx < s->num_context) + plic__context_enable_write(s, + &s->contexts[cntx], + addr, data); + } else if (CONTEXT_BASE <= addr && addr < REG_SIZE) { + cntx = (addr - CONTEXT_BASE) / CONTEXT_PER_HART; + addr -= cntx * CONTEXT_PER_HART + CONTEXT_BASE; + if (cntx < s->num_context) + plic__context_write(s, &s->contexts[cntx], + addr, data); + } + } else { + if (PRIORITY_BASE <= addr && addr < ENABLE_BASE) { + plic__priority_read(s, addr, data); + } else if (ENABLE_BASE <= addr && addr < CONTEXT_BASE) { + cntx = (addr - ENABLE_BASE) / ENABLE_PER_HART; + addr -= cntx * ENABLE_PER_HART + ENABLE_BASE; + if (cntx < s->num_context) + plic__context_enable_read(s, + &s->contexts[cntx], + addr, data); + } else if (CONTEXT_BASE <= addr && addr < REG_SIZE) { + cntx = (addr - CONTEXT_BASE) / CONTEXT_PER_HART; + addr -= cntx * CONTEXT_PER_HART + CONTEXT_BASE; + if (cntx < s->num_context) + plic__context_read(s, &s->contexts[cntx], + addr, data); + } + } +} + +static int plic__init(struct kvm *kvm) +{ + u32 i; + int ret; + struct plic_context *c; + + plic.kvm = kvm; + plic.dev_hdr = (struct device_header) { + .bus_type = DEVICE_BUS_MMIO, + }; + + plic.num_irq = MAX_DEVICES; + plic.num_irq_word = plic.num_irq / 32; + if ((plic.num_irq_word * 32) < plic.num_irq) + plic.num_irq_word++; + plic.max_prio = (1UL << PRIORITY_PER_ID) - 1; + + plic.num_context = kvm->nrcpus * 2; + plic.contexts = calloc(plic.num_context, sizeof(struct plic_context)); + if (!plic.contexts) + return -ENOMEM; + for (i = 0; i < plic.num_context; i++) { + c = &plic.contexts[i]; + c->s = &plic; + c->num = i; + c->vcpu = kvm->cpus[i / 2]; + mutex_init(&c->irq_lock); + } + + mutex_init(&plic.irq_lock); + + ret = kvm__register_mmio(kvm, RISCV_PLIC, RISCV_PLIC_SIZE, + false, plic__mmio_callback, &plic); + if (ret) + return ret; + + ret = device__register(&plic.dev_hdr); + if (ret) + return ret; + + plic.ready = true; + + return 0; + +} +dev_init(plic__init); + +static int plic__exit(struct kvm *kvm) +{ + plic.ready = false; + kvm__deregister_mmio(kvm, RISCV_PLIC); + free(plic.contexts); + + return 0; +} +dev_exit(plic__exit); From patchwork Mon Sep 27 11:42:25 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anup Patel X-Patchwork-Id: 12519643 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 05832C433EF for ; Mon, 27 Sep 2021 11:43:25 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E275860F4B for ; Mon, 27 Sep 2021 11:43:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234389AbhI0LpB (ORCPT ); Mon, 27 Sep 2021 07:45:01 -0400 Received: from esa6.hgst.iphmx.com ([216.71.154.45]:36563 "EHLO esa6.hgst.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234189AbhI0Lon (ORCPT ); Mon, 27 Sep 2021 07:44:43 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=wdc.com; i=@wdc.com; q=dns/txt; s=dkim.wdc.com; t=1632742986; x=1664278986; h=from:to:cc:subject:date:message-id:in-reply-to: references:content-transfer-encoding:mime-version; bh=qyjSXJELHWvSvV9oYRAheCP/Wi4KRzpZ4SoeSJ+ZCFg=; b=j8K2M2gqzr4Ei1QI8S27rx50B8eShMfh2qMJjsOp0LEuQAVd3s61KlMJ DveeqTZ/h/F2r7o7D5UwgUR1YDJ6+T+KEo2nHXEjGMV+uFWRXmOH3vigj a1dzmHExDKtkS0mWv+lQ8bv197op90oXHrFQPPjGZYmYgipvFPhademnt oG9s4VFZ2zvyFmnbIYFuvO6pXFrlNdvJ89VTIGNualMlj8DHYtMGdrz3m JBi0Q3cAcPn2EkNkvYZ0o//Wvo5+ASpSryjuwIMb4T7HiSaWhlncrc/sY 9t0qNQtlUGpUbsn482T3O8qiYmL0+SN8+xflChQqVgtGo/ww3x3UZqcbd g==; X-IronPort-AV: E=Sophos;i="5.85,326,1624291200"; d="scan'208";a="181673176" Received: from mail-bn8nam08lp2044.outbound.protection.outlook.com (HELO NAM04-BN8-obe.outbound.protection.outlook.com) ([104.47.74.44]) by ob1.hgst.iphmx.com with ESMTP; 27 Sep 2021 19:43:05 +0800 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=iVyZ5j4IAFV0sfSiW4YYsllWuBdx7fEGTjxCFiEyZ3tC/xtMhBEbzMnpjGX26KQkTOex5EAjGkPQVGPL0RvIGP8Nw7q5Qs9FZ7xaLra3UN1VPw7/GrOVOPPlKREQwaOJCBiV6NrqfPL/ZeTTA0m6WpxHI0oZSzVdFdi56vOlsaYQkafE0BxNgov90dq7QnnzXO5Pc4aL/fs5vZ1z/tkjXuQ/hh7WikfX/1RjnPXZ9zGMFNqy4xmHAq9agvgbev79VI5CBN0Ctav0YiXNSJpjoMRFvjaWb4hon6taGs20ysGHTJv594edSKDHCh3tOC1H4B+nt3/3vErUCup36gZKtQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=08yt89Q9GIfVQt8YmX3rqkut9qjhcuJwoF9DcI15KWc=; b=giZV0ZNBBJ5leD0vRS6UDvCCL5HQzs5Qix+/bEksye35y5Lac9H5eP1Sn6zy66zAvGGb2g+MZ/Ds3VjVlqZXKwSMCNiFPjZ4w8eG224HxTfq9X+IVj3cLLjvKX8cp3deTXxQI5tJOQuPkJZz/zIaYTpgiK1ecSjutsO3++Ipx5DszGg/+/UuQV9Rl8gi/HqkSmR1gl0bwkoNPm6JzUP7SGdKxPTuhmQyaw3TrS2cQbznz5zSMzWQ7UXYqy5X2tIarvUUGCyuFBiV9dLxyEd5ID+Aq4AJwkmpik/5OxgjP1N46sUSu/gH2egYmpBGdU2a1Qxd+2LZdfA9XlcOLgHunw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=wdc.com; dmarc=pass action=none header.from=wdc.com; dkim=pass header.d=wdc.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sharedspace.onmicrosoft.com; s=selector2-sharedspace-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=08yt89Q9GIfVQt8YmX3rqkut9qjhcuJwoF9DcI15KWc=; b=jt8+O59XgmMeD33McqtE9m6/paow+4uMFg/O7S/dacs32EBQuvBWkg6TFoGUFpumoOmbDQqeCP6B5iRjGDxSDTMcltydxOl8ceeBHv/ByEHHBYawkisaMe5yqFiOUUkoOOX7EwJ0PRQ6Cx41hcoIV7INgHcat4Aai7YCYqOU0qA= Authentication-Results: kernel.org; dkim=none (message not signed) header.d=none;kernel.org; dmarc=none action=none header.from=wdc.com; Received: from CO6PR04MB7812.namprd04.prod.outlook.com (2603:10b6:303:138::6) by CO6PR04MB7841.namprd04.prod.outlook.com (2603:10b6:5:358::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4544.13; Mon, 27 Sep 2021 11:43:03 +0000 Received: from CO6PR04MB7812.namprd04.prod.outlook.com ([fe80::6830:650b:8265:af0b]) by CO6PR04MB7812.namprd04.prod.outlook.com ([fe80::6830:650b:8265:af0b%6]) with mapi id 15.20.4544.021; Mon, 27 Sep 2021 11:43:03 +0000 From: Anup Patel To: Will Deacon Cc: Paolo Bonzini , Atish Patra , Alistair Francis , Anup Patel , kvm@vger.kernel.org, kvm-riscv@lists.infradead.org, Anup Patel Subject: [PATCH v9 6/8] riscv: Generate FDT at runtime for Guest/VM Date: Mon, 27 Sep 2021 17:12:25 +0530 Message-Id: <20210927114227.1089403-7-anup.patel@wdc.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210927114227.1089403-1-anup.patel@wdc.com> References: <20210927114227.1089403-1-anup.patel@wdc.com> X-ClientProxiedBy: MA1PR01CA0173.INDPRD01.PROD.OUTLOOK.COM (2603:1096:a01:d::14) To CO6PR04MB7812.namprd04.prod.outlook.com (2603:10b6:303:138::6) MIME-Version: 1.0 Received: from wdc.com (122.179.75.205) by MA1PR01CA0173.INDPRD01.PROD.OUTLOOK.COM (2603:1096:a01:d::14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4544.14 via Frontend Transport; Mon, 27 Sep 2021 11:43:00 +0000 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: e6deb653-3c8d-4af3-dcb1-08d981abf6ae X-MS-TrafficTypeDiagnostic: CO6PR04MB7841: X-MS-Exchange-Transport-Forked: True X-Microsoft-Antispam-PRVS: WDCIPOUTBOUND: EOP-TRUE X-MS-Oob-TLC-OOBClassifiers: OLM:31; X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: juCtLdGxqIgk/s47YG2dZnl67/Qwxl0xRJtWSoXs1+IP8U6WfmGgcciF1dESAnrOtS4yeI1NuP9BXB6WWGN/BOOfJDX3FDzXdSV1Bp+3fGZneRh3jWDOJBnrkmoDmQ8xCxa9fAs6Y4fQV3OdG0lxeeFvNJaMdCWp3wWjaokC3KA3q5sOIoCtE54TIF1i+Glh5rIW5Dwm4921LfhgUYe9OzHr6qDvSyvH9PgMg8SFasJJFMAo5HuC6J1QH1U7XQXuDGWBKDD7eOJs+INc1hWm8r4XoTLnG596E3F2g7U1w11uWb1YhYaylNXic1wYhW0QRBwC48cBbUsHDyQeXDV5WBcOmaLIrgZWAoOhSt549C2B6bF2FKirchUcPnDJkJJPdZsC4fwIKDZ7FV3aUMoQya8khkN8RWASjO5GSlunT06z+pchsdTUg275CbSp827dyWTCQb65C2RB4hEOvIBpZeP4XNCpWMrdOirD0r1JBIeAI1l/azh26vK6ogpyJpQ/cTGPn90vM1oOmeFA8nQupNpkJYAERq6lmkUsiwzFc0BUNzGUoUq8AAskXM5bWNO/mSl55PioNZ9m2qIMtr7zThs/XgnFfPA8aJw1h0bOFNOVbXIvj2tbxCxp+u6Iwz1pUPLPWCvWsO3mvQx5jv49fmRp6ITQyUOyltfzu9rsuO4QWTMU4mR4y0JSEXGCgEfZ44B5KaeDXH+NoAC3BduM5Q== X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:CO6PR04MB7812.namprd04.prod.outlook.com;PTR:;CAT:NONE;SFS:(4636009)(366004)(54906003)(316002)(5660300002)(1076003)(66556008)(83380400001)(30864003)(66946007)(66476007)(36756003)(38100700002)(38350700002)(55016002)(86362001)(508600001)(6916009)(44832011)(8886007)(6666004)(2906002)(8676002)(956004)(2616005)(7696005)(8936002)(4326008)(26005)(52116002)(186003);DIR:OUT;SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: ckUGfqp0XOUwsUqysW7SfWODTGV9PSsD2jDlQ5xuyrLXU12E4LEpCbIhGUXtPZtxrR4pEAbXestp2EyuHtn0XuvH8Pn4u4k4wi29LDCwPVbYxNa3KXccEKOhXURUiAtwb/YNEM+exPPn7ura5GSnbHBbyJNJdiMl82qMSo0JDmvA81D5K71jfZhSGx5Uiks7CUs+H7so6iAGoOA5HYqwAe9kxXA5oLG6BG85UJp55oX8S6IIMhIlI2ymJPNqWEif8S/PRojG+r+8Qg+bEhSnyCbFfwEUC/xSmpmj0ZpBlo8owfjrstYF8ozNcEeW32JkczNBHzWzuaoEstbKwX4UWm+uARj2J+GRsbkkY4KE16yVFgJRW8TxtMLD0PJa2dQ6ysRJI7F1+aDNZeINpKu9dQ1dTxuDW/lHdrDYkanDIflVm9R8IrjrUfdDOljl7c8Ap03gXONR5/0FCtEMKGFjM9QjD10cIE7HuspIhltcxP+f0CP6jwL7BfiALJ/RUtKpIqC3bB7ZA2kLHMFIPIzv2s/DKKTPRFfX+6qdxCTHyMK0OrLFFVTHEij3yKk5+Ido5VkgMDnR/Iy1hjLh1xTUoaanOijP/sdIhmylGZVjFZ5mmGiL/LR92gGzhtWezi7FW90eFDBQJLUQXOWJlJ64oOBofCKoMsJ8RykE6a03h1YfIE4jy0e9kBXKF5eV7dcMADy74YkamSHo2+HuVIwkSuHvMwNvsey6S3FUhjGaMmqQewiIW6z2dIkPAv95Jtx3BkxnojsW7aTja59yWRIK+GqEajMeQ3ni6ighg0FKoHcm2s1DVTBW3fYAETlAvqOVs9FJxiz+4z21noOPSUidaoYvouacpmMtsw5bFzN9sIYQ/VaAqzQqshm1rBg16wsod0MwV7pzPoEiQKEzVJhquLGMug64SZsfVs4s3ia2B0TWoam1v/eNyMZnmpPTiXh8DzTfU2VO6++NEMYJzyACb4Jjd98lKACBs5TVrzo4Q5ddkDw5h2B1dQo3o49rvY8t2nTWliWm3oyOs5kv5DPGN73UiHpw86HuVNo85KdQJ6ssBUTLN6ULKgquW02mUTSF3zX96feaJwwKSf8yV9YvkbPXek053Mrzafzrg0xag9gt+TkH4o6nw01uO8rngUM0A8vrZ8FlgAvvLLUsS3nPDwkkM6aOzx3YBDnRMc5+ICFqNZ4v0ToHKmGIiiNO9JZx1eyw4Q374hP2xlbWj6IL6XM70JV92ctLJzBLxWddz39fCv8OnAY7wQnheh1o2TFwD4Vr7YYjpLfYUyDXLj8XeG1+clmun9RUkJk+YMaNYpKwqzozyTpHY3d3N39Ukc3/ X-OriginatorOrg: wdc.com X-MS-Exchange-CrossTenant-Network-Message-Id: e6deb653-3c8d-4af3-dcb1-08d981abf6ae X-MS-Exchange-CrossTenant-AuthSource: CO6PR04MB7812.namprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 27 Sep 2021 11:43:02.8846 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: b61c8803-16f3-4c35-9b17-6f65f441df86 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: sj9Yk4jtyh4FGJICHQBXZJXP6zlSMk5xn5frvWHYSAWMwKDxnzApEwR+yHbTK+tZcW/tY+HMJ/VsotZhd6oeww== X-MS-Exchange-Transport-CrossTenantHeadersStamped: CO6PR04MB7841 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org We generate FDT at runtime for RISC-V Guest/VM so that KVMTOOL users don't have to pass FDT separately via command-line parameters. Also, we provide "--dump-dtb " command-line option to dump generated FDT into a file for debugging purpose. Signed-off-by: Atish Patra Signed-off-by: Anup Patel --- Makefile | 1 + riscv/fdt.c | 192 ++++++++++++++++++++++++++++ riscv/include/kvm/fdt-arch.h | 4 + riscv/include/kvm/kvm-arch.h | 2 + riscv/include/kvm/kvm-config-arch.h | 6 + riscv/plic.c | 50 ++++++++ 6 files changed, 255 insertions(+) create mode 100644 riscv/fdt.c diff --git a/Makefile b/Makefile index eacf766..e4e1184 100644 --- a/Makefile +++ b/Makefile @@ -199,6 +199,7 @@ endif ifeq ($(ARCH),riscv) DEFINES += -DCONFIG_RISCV ARCH_INCLUDE := riscv/include + OBJS += riscv/fdt.o OBJS += riscv/ioport.o OBJS += riscv/irq.o OBJS += riscv/kvm.o diff --git a/riscv/fdt.c b/riscv/fdt.c new file mode 100644 index 0000000..6527ef7 --- /dev/null +++ b/riscv/fdt.c @@ -0,0 +1,192 @@ +#include "kvm/devices.h" +#include "kvm/fdt.h" +#include "kvm/kvm.h" +#include "kvm/kvm-cpu.h" + +#include + +#include +#include +#include + +static void dump_fdt(const char *dtb_file, void *fdt) +{ + int count, fd; + + fd = open(dtb_file, O_CREAT | O_TRUNC | O_RDWR, 0666); + if (fd < 0) + die("Failed to write dtb to %s", dtb_file); + + count = write(fd, fdt, FDT_MAX_SIZE); + if (count < 0) + die_perror("Failed to dump dtb"); + + pr_debug("Wrote %d bytes to dtb %s", count, dtb_file); + close(fd); +} + +#define CPU_NAME_MAX_LEN 15 +#define CPU_ISA_MAX_LEN 128 +static void generate_cpu_nodes(void *fdt, struct kvm *kvm) +{ + int cpu, pos, i, index, valid_isa_len; + const char *valid_isa_order = "IEMAFDQCLBJTPVNSUHKORWXYZG"; + + _FDT(fdt_begin_node(fdt, "cpus")); + _FDT(fdt_property_cell(fdt, "#address-cells", 0x1)); + _FDT(fdt_property_cell(fdt, "#size-cells", 0x0)); + _FDT(fdt_property_cell(fdt, "timebase-frequency", + kvm->cpus[0]->riscv_timebase)); + + for (cpu = 0; cpu < kvm->nrcpus; ++cpu) { + char cpu_name[CPU_NAME_MAX_LEN]; + char cpu_isa[CPU_ISA_MAX_LEN]; + struct kvm_cpu *vcpu = kvm->cpus[cpu]; + + snprintf(cpu_name, CPU_NAME_MAX_LEN, "cpu@%x", cpu); + + snprintf(cpu_isa, CPU_ISA_MAX_LEN, "rv%ld", vcpu->riscv_xlen); + pos = strlen(cpu_isa); + valid_isa_len = strlen(valid_isa_order); + for (i = 0; i < valid_isa_len; i++) { + index = valid_isa_order[i] - 'A'; + if (vcpu->riscv_isa & (1 << (index))) + cpu_isa[pos++] = 'a' + index; + } + cpu_isa[pos] = '\0'; + + _FDT(fdt_begin_node(fdt, cpu_name)); + _FDT(fdt_property_string(fdt, "device_type", "cpu")); + _FDT(fdt_property_string(fdt, "compatible", "riscv")); + if (vcpu->riscv_xlen == 64) + _FDT(fdt_property_string(fdt, "mmu-type", + "riscv,sv48")); + else + _FDT(fdt_property_string(fdt, "mmu-type", + "riscv,sv32")); + _FDT(fdt_property_string(fdt, "riscv,isa", cpu_isa)); + _FDT(fdt_property_cell(fdt, "reg", cpu)); + _FDT(fdt_property_string(fdt, "status", "okay")); + + _FDT(fdt_begin_node(fdt, "interrupt-controller")); + _FDT(fdt_property_string(fdt, "compatible", "riscv,cpu-intc")); + _FDT(fdt_property_cell(fdt, "#interrupt-cells", 1)); + _FDT(fdt_property(fdt, "interrupt-controller", NULL, 0)); + _FDT(fdt_property_cell(fdt, "phandle", + PHANDLE_CPU_INTC_BASE + cpu)); + _FDT(fdt_end_node(fdt)); + + _FDT(fdt_end_node(fdt)); + } + + _FDT(fdt_end_node(fdt)); +} + +static int setup_fdt(struct kvm *kvm) +{ + struct device_header *dev_hdr; + u8 staging_fdt[FDT_MAX_SIZE]; + u64 mem_reg_prop[] = { + cpu_to_fdt64(kvm->arch.memory_guest_start), + cpu_to_fdt64(kvm->ram_size), + }; + void *fdt = staging_fdt; + void *fdt_dest = guest_flat_to_host(kvm, + kvm->arch.dtb_guest_start); + void (*generate_mmio_fdt_nodes)(void *, struct device_header *, + void (*)(void *, u8, enum irq_type)); + + /* Create new tree without a reserve map */ + _FDT(fdt_create(fdt, FDT_MAX_SIZE)); + _FDT(fdt_finish_reservemap(fdt)); + + /* Header */ + _FDT(fdt_begin_node(fdt, "")); + _FDT(fdt_property_string(fdt, "compatible", "linux,dummy-virt")); + _FDT(fdt_property_cell(fdt, "#address-cells", 0x2)); + _FDT(fdt_property_cell(fdt, "#size-cells", 0x2)); + + /* /chosen */ + _FDT(fdt_begin_node(fdt, "chosen")); + + /* Pass on our amended command line to a Linux kernel only. */ + if (kvm->cfg.firmware_filename) { + if (kvm->cfg.kernel_cmdline) + _FDT(fdt_property_string(fdt, "bootargs", + kvm->cfg.kernel_cmdline)); + } else + _FDT(fdt_property_string(fdt, "bootargs", + kvm->cfg.real_cmdline)); + + _FDT(fdt_property_string(fdt, "stdout-path", "serial0")); + + /* Initrd */ + if (kvm->arch.initrd_size != 0) { + u64 ird_st_prop = cpu_to_fdt64(kvm->arch.initrd_guest_start); + u64 ird_end_prop = cpu_to_fdt64(kvm->arch.initrd_guest_start + + kvm->arch.initrd_size); + + _FDT(fdt_property(fdt, "linux,initrd-start", + &ird_st_prop, sizeof(ird_st_prop))); + _FDT(fdt_property(fdt, "linux,initrd-end", + &ird_end_prop, sizeof(ird_end_prop))); + } + + _FDT(fdt_end_node(fdt)); + + /* Memory */ + _FDT(fdt_begin_node(fdt, "memory")); + _FDT(fdt_property_string(fdt, "device_type", "memory")); + _FDT(fdt_property(fdt, "reg", mem_reg_prop, sizeof(mem_reg_prop))); + _FDT(fdt_end_node(fdt)); + + /* CPUs */ + generate_cpu_nodes(fdt, kvm); + + /* Simple Bus */ + _FDT(fdt_begin_node(fdt, "smb")); + _FDT(fdt_property_string(fdt, "compatible", "simple-bus")); + _FDT(fdt_property_cell(fdt, "#address-cells", 0x2)); + _FDT(fdt_property_cell(fdt, "#size-cells", 0x2)); + _FDT(fdt_property_cell(fdt, "interrupt-parent", PHANDLE_PLIC)); + _FDT(fdt_property(fdt, "ranges", NULL, 0)); + + /* Virtio MMIO devices */ + dev_hdr = device__first_dev(DEVICE_BUS_MMIO); + while (dev_hdr) { + generate_mmio_fdt_nodes = dev_hdr->data; + generate_mmio_fdt_nodes(fdt, dev_hdr, plic__generate_irq_prop); + dev_hdr = device__next_dev(dev_hdr); + } + + /* IOPORT devices */ + dev_hdr = device__first_dev(DEVICE_BUS_IOPORT); + while (dev_hdr) { + generate_mmio_fdt_nodes = dev_hdr->data; + generate_mmio_fdt_nodes(fdt, dev_hdr, plic__generate_irq_prop); + dev_hdr = device__next_dev(dev_hdr); + } + + _FDT(fdt_end_node(fdt)); + + if (fdt_stdout_path) { + _FDT(fdt_begin_node(fdt, "aliases")); + _FDT(fdt_property_string(fdt, "serial0", fdt_stdout_path)); + _FDT(fdt_end_node(fdt)); + + free(fdt_stdout_path); + fdt_stdout_path = NULL; + } + + /* Finalise. */ + _FDT(fdt_end_node(fdt)); + _FDT(fdt_finish(fdt)); + + _FDT(fdt_open_into(fdt, fdt_dest, FDT_MAX_SIZE)); + _FDT(fdt_pack(fdt_dest)); + + if (kvm->cfg.arch.dump_dtb_filename) + dump_fdt(kvm->cfg.arch.dump_dtb_filename, fdt_dest); + return 0; +} +late_init(setup_fdt); diff --git a/riscv/include/kvm/fdt-arch.h b/riscv/include/kvm/fdt-arch.h index 9450fc5..f7548e8 100644 --- a/riscv/include/kvm/fdt-arch.h +++ b/riscv/include/kvm/fdt-arch.h @@ -1,4 +1,8 @@ #ifndef KVM__KVM_FDT_H #define KVM__KVM_FDT_H +enum phandles {PHANDLE_RESERVED = 0, PHANDLE_PLIC, PHANDLES_MAX}; + +#define PHANDLE_CPU_INTC_BASE PHANDLES_MAX + #endif /* KVM__KVM_FDT_H */ diff --git a/riscv/include/kvm/kvm-arch.h b/riscv/include/kvm/kvm-arch.h index 9face96..884c16b 100644 --- a/riscv/include/kvm/kvm-arch.h +++ b/riscv/include/kvm/kvm-arch.h @@ -78,6 +78,8 @@ static inline bool riscv_addr_in_ioport_region(u64 phys_addr) enum irq_type; +void plic__generate_irq_prop(void *fdt, u8 irq, enum irq_type irq_type); + void plic__irq_trig(struct kvm *kvm, int irq, int level, bool edge); #endif /* KVM__KVM_ARCH_H */ diff --git a/riscv/include/kvm/kvm-config-arch.h b/riscv/include/kvm/kvm-config-arch.h index 60c7333..526fca2 100644 --- a/riscv/include/kvm/kvm-config-arch.h +++ b/riscv/include/kvm/kvm-config-arch.h @@ -4,6 +4,12 @@ #include "kvm/parse-options.h" struct kvm_config_arch { + const char *dump_dtb_filename; }; +#define OPT_ARCH_RUN(pfx, cfg) \ + pfx, \ + OPT_STRING('\0', "dump-dtb", &(cfg)->dump_dtb_filename, \ + ".dtb file", "Dump generated .dtb to specified file"), + #endif /* KVM__KVM_CONFIG_ARCH_H */ diff --git a/riscv/plic.c b/riscv/plic.c index d71226e..9344202 100644 --- a/riscv/plic.c +++ b/riscv/plic.c @@ -1,5 +1,6 @@ #include "kvm/devices.h" +#include "kvm/fdt.h" #include "kvm/ioeventfd.h" #include "kvm/ioport.h" #include "kvm/kvm.h" @@ -460,6 +461,54 @@ static void plic__mmio_callback(struct kvm_cpu *vcpu, } } +void plic__generate_irq_prop(void *fdt, u8 irq, enum irq_type irq_type) +{ + u32 irq_prop[] = { + cpu_to_fdt32(irq) + }; + + _FDT(fdt_property(fdt, "interrupts", irq_prop, sizeof(irq_prop))); +} + +static void plic__generate_fdt_node(void *fdt, + struct device_header *dev_hdr, + void (*generate_irq_prop)(void *fdt, + u8 irq, + enum irq_type)) +{ + u32 i; + u32 reg_cells[4], *irq_cells; + + reg_cells[0] = 0; + reg_cells[1] = cpu_to_fdt32(RISCV_PLIC); + reg_cells[2] = 0; + reg_cells[3] = cpu_to_fdt32(RISCV_PLIC_SIZE); + + irq_cells = calloc(plic.num_context * 2, sizeof(u32)); + if (!irq_cells) + die("Failed to alloc irq_cells"); + + _FDT(fdt_begin_node(fdt, "interrupt-controller@0c000000")); + _FDT(fdt_property_string(fdt, "compatible", "riscv,plic0")); + _FDT(fdt_property(fdt, "reg", reg_cells, sizeof(reg_cells))); + _FDT(fdt_property_cell(fdt, "#interrupt-cells", 1)); + _FDT(fdt_property(fdt, "interrupt-controller", NULL, 0)); + _FDT(fdt_property_cell(fdt, "riscv,max-priority", plic.max_prio)); + _FDT(fdt_property_cell(fdt, "riscv,ndev", MAX_DEVICES - 1)); + _FDT(fdt_property_cell(fdt, "phandle", PHANDLE_PLIC)); + for (i = 0; i < (plic.num_context / 2); i++) { + irq_cells[4*i + 0] = cpu_to_fdt32(PHANDLE_CPU_INTC_BASE + i); + irq_cells[4*i + 1] = cpu_to_fdt32(0xffffffff); + irq_cells[4*i + 2] = cpu_to_fdt32(PHANDLE_CPU_INTC_BASE + i); + irq_cells[4*i + 3] = cpu_to_fdt32(9); + } + _FDT(fdt_property(fdt, "interrupts-extended", irq_cells, + sizeof(u32) * plic.num_context * 2)); + _FDT(fdt_end_node(fdt)); + + free(irq_cells); +} + static int plic__init(struct kvm *kvm) { u32 i; @@ -469,6 +518,7 @@ static int plic__init(struct kvm *kvm) plic.kvm = kvm; plic.dev_hdr = (struct device_header) { .bus_type = DEVICE_BUS_MMIO, + .data = plic__generate_fdt_node, }; plic.num_irq = MAX_DEVICES; From patchwork Mon Sep 27 11:42:26 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anup Patel X-Patchwork-Id: 12519645 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C50C0C433FE for ; Mon, 27 Sep 2021 11:43:26 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id B11CE60F6C for ; Mon, 27 Sep 2021 11:43:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234301AbhI0LpD (ORCPT ); Mon, 27 Sep 2021 07:45:03 -0400 Received: from esa1.hgst.iphmx.com ([68.232.141.245]:50214 "EHLO esa1.hgst.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234269AbhI0Lop (ORCPT ); Mon, 27 Sep 2021 07:44:45 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=wdc.com; i=@wdc.com; q=dns/txt; s=dkim.wdc.com; t=1632742987; x=1664278987; h=from:to:cc:subject:date:message-id:in-reply-to: references:content-transfer-encoding:mime-version; bh=lDq+FKo7RmMLlDr7OA4J8sRiNlAUgKGsONyvb6DEe/M=; b=gNm3T3tmHG6rFhGmzz7uVHVVbMPn4WO/d9cz7WKkLfbnetO1B7BlrMUt BgkIDSA4wiJ8hTPowmODuxpmTTYZXjlp4nltvLLhxTlvvHhbtit4QEzmY Ox0zkob4YUnwLzBvR4s7PwdHuc41axWveBpLIeKBG5HgjRU1ug3DJNHWx TPtN1oemBSKBKwqrrlCrvlwjmLR3qxazr/4b2pK+AU70cXnZ6xYKODjmg pypJigDxXtSb62y+JjeVzstFgUBN+aeOOycUfUtRhQtAlB4/wvAllO/i5 cqo20ONYtNBndTLP4uH3NaATlFmHvQfKoQAmsdZUWTxwDyj2N1vFo4ka+ g==; X-IronPort-AV: E=Sophos;i="5.85,326,1624291200"; d="scan'208";a="292706622" Received: from mail-bn8nam12lp2170.outbound.protection.outlook.com (HELO NAM12-BN8-obe.outbound.protection.outlook.com) ([104.47.55.170]) by ob1.hgst.iphmx.com with ESMTP; 27 Sep 2021 19:43:06 +0800 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=oVtAXAx0pw9oS58treJmGtNboIMbAKKXtoSStmPz5vs6ZIfeSAlaZlzb6XUzGIRHZWignXR3V06tBv7Eck+KXNXN4Hoxu8nQhSzyLshzImM+YT9Q02sRuAdg4QT9qVLq5ovsVKebb5xkv4wQgFE/HuHPFGrPhp97LTCY+Gpk/tltf8/F3G+1ZVTKvAH7l/tLC8qewl1VqMDC0jFzDNiHDBox4LncU1TcLjV3f6Oteqg8T0xuVLoYOeNjPusH0VGS2Lhkqxarw0ygiKDuW1hxAs0wB2wo55J+/JOi+Rf3hbead71GyzeI9awHLwdPCnDfPZJvEjg7ZA1jyBXCFOH0+Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=yrurI0CrHyGTFt1VaTothhQZAEntRUm1BYM8Wyf5F+M=; b=KWwW5HU4Gx1zNo1ea7JxJV9ryGKUMtrNiVffsw95moY8LsLLUbAj0GWWnAaHa8HBhm2HAKwtGtE+1bmKdj79mKgNewvxjM1A6DU/kBFs/xPsyAhI7ZG/q/ipHCaD/e4H5DDJ0klwdezMDa3rnWOEE56uptuUGYEnHXkbm8sURKtBYyzBsRWZRTvH3HSfC3KC+1n1thOIXD1DcY56FiZFZPUPHljofuSfTFXkoRDdnlsV8dAjzwzJCTMXr3egq/U4GS0VDpmYESsUF31mqItutU4kdfE7n5BFzaoCLABnj+0ZKfJ8LE0dj28zJSDw5U1TRKz37nB6nk7q+BXoaw/FjA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=wdc.com; dmarc=pass action=none header.from=wdc.com; dkim=pass header.d=wdc.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sharedspace.onmicrosoft.com; s=selector2-sharedspace-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=yrurI0CrHyGTFt1VaTothhQZAEntRUm1BYM8Wyf5F+M=; b=jjAwsrSZNbNVfXBNTmLmFvGdgKahb2wIDEsT6T4Kd2T5YIsVwORFaikebdkTF8/zMbaERojTfWjhMEjeznLEwqsGw3WiduqRvaiTP7f3ds5iqR6O8hZXOR4zxoWjVwXiBDsLGL3sGUjOH59fxyGXnbK9gKc76vEMZ50ivD+t5Pw= Authentication-Results: kernel.org; dkim=none (message not signed) header.d=none;kernel.org; dmarc=none action=none header.from=wdc.com; Received: from CO6PR04MB7812.namprd04.prod.outlook.com (2603:10b6:303:138::6) by CO6PR04MB7841.namprd04.prod.outlook.com (2603:10b6:5:358::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4544.13; Mon, 27 Sep 2021 11:43:05 +0000 Received: from CO6PR04MB7812.namprd04.prod.outlook.com ([fe80::6830:650b:8265:af0b]) by CO6PR04MB7812.namprd04.prod.outlook.com ([fe80::6830:650b:8265:af0b%6]) with mapi id 15.20.4544.021; Mon, 27 Sep 2021 11:43:05 +0000 From: Anup Patel To: Will Deacon Cc: Paolo Bonzini , Atish Patra , Alistair Francis , Anup Patel , kvm@vger.kernel.org, kvm-riscv@lists.infradead.org, Anup Patel Subject: [PATCH v9 7/8] riscv: Handle SBI calls forwarded to user space Date: Mon, 27 Sep 2021 17:12:26 +0530 Message-Id: <20210927114227.1089403-8-anup.patel@wdc.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210927114227.1089403-1-anup.patel@wdc.com> References: <20210927114227.1089403-1-anup.patel@wdc.com> X-ClientProxiedBy: MA1PR01CA0173.INDPRD01.PROD.OUTLOOK.COM (2603:1096:a01:d::14) To CO6PR04MB7812.namprd04.prod.outlook.com (2603:10b6:303:138::6) MIME-Version: 1.0 Received: from wdc.com (122.179.75.205) by MA1PR01CA0173.INDPRD01.PROD.OUTLOOK.COM (2603:1096:a01:d::14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4544.14 via Frontend Transport; Mon, 27 Sep 2021 11:43:03 +0000 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 8581a0a7-ebb9-48ef-72c6-08d981abf835 X-MS-TrafficTypeDiagnostic: CO6PR04MB7841: X-MS-Exchange-Transport-Forked: True X-Microsoft-Antispam-PRVS: WDCIPOUTBOUND: EOP-TRUE X-MS-Oob-TLC-OOBClassifiers: OLM:2803; X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: lu9sfRioGMgdtp21iHTeEl7Rl4XpMMuBufJoBq3PkDglm9I33SdpvPBszjnH5jsK6svXiUUptDqjjs/BohFi+mc0eiZ+ATYRuz+IAPWD9wjYm+GNSdiOSfGvb5SzUFfJuSitd23kpiuFePuyGYx3kIQMI9naCqIzSHJQSaW/dKlC5UdiL887JodzjXlxBRqlC8M9rerrrPYi6rKFnY7RZLn9VFBr4Xp4WU6e4YfoiASmcLtJJQN9dWtGvettwDYmvxGOOs8+cdFQXtBdD2Y9VoQJDM0GTkaxAxiKQRwP/zB8AQwK3wGX5MPa8BdG78vaZRdMPqVt+m67vcDNAnRCOfdMbUj/CFlWjtnofYtMNWEmOsB8EoB1b/LmqbPPDUtkjmPJerXWTD50MQvIsHAlQYIgLJdsU6Fj6dP46owK5sKHQhCxj7pmhCNrueXhJFl8t74OAOuK6HolLzmKaFodzcEJsR5zRVW1lIkCXJdufV4VRx2YkGpZLiGqiUZ/xSk83y9Oy/vtkuQAO7OiElCz23izJdg64F98NHcljZRLEfUrmD4eqW/SVqC5FEXcKZwx4sCex5KpUKjPbGdsrMAHqu9GRT4lRYvGXwi9KJG5RyIkZeC2VwFjXETo44YfqeMXDUWCMq3np4IW9iGlhYWBTKuAvldplaZLj4y5U8nhZUjDw8h8yLSpIRySFvzzTyaz X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:CO6PR04MB7812.namprd04.prod.outlook.com;PTR:;CAT:NONE;SFS:(4636009)(366004)(54906003)(316002)(5660300002)(1076003)(66556008)(83380400001)(66946007)(66476007)(36756003)(38100700002)(38350700002)(55016002)(86362001)(508600001)(6916009)(44832011)(8886007)(6666004)(2906002)(8676002)(956004)(2616005)(7696005)(8936002)(4326008)(26005)(52116002)(186003);DIR:OUT;SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: 4dpngnTH0EEc5dPkPAuNVMwwGckGpqH6Fh7FeDk5EHj+CkJxSiUIthsruutaSbk8YPPj0eYT/7skQRI0Aan0RAGZfdJomOHgGtpzJRFlsuwasgoDRW7Q9757+JbVgPTrRmY6v6Fz7A98qdbdLBRXPYzg23ziNBo6U3V1v96wVyx7tOPCDNvr2TctrPmeoXQuRW4lIs7tnzZVdsvP8uAzp5m+kZ5xAzDJeiNA9ju7PTBzXt6eAcnsuZc5T6AO83m1IACCFM5jXItnF9OMNRE9Kovd5NVz+0UQkefmm5lluqNzyyqNOkhQT9gkSXnDyfNB2W1apvFwqDM70jdUNjpGkjWL8Ror3fhEozRUpT3xZbgxyPJsEiTroL2J4oqiPRWNmRs/DM0lpiN0bGN6xdMxPQJK0RdUQv5kx6cqrqCyiq0XJgCVKw4wb8TA3JGrx4ANT/TkstVzOKm8iyDAPBze2czxX9gXnhwsDyYTowq9/+ngVHLasjiASgIEOz1INoPzUSRdM+as1oaAKp1dHBFMHwx8ayeevjAt0khw9wUvaMNsxstm/WpASRL64zhUj5JKctCre9ISUU/egbGgGMDTiXIQoCuXgLkPv4HY3CMVdrso4BRE+tbt4dByfC9Z2gxJNaK2fDHLsBgSDpg1rUuYS9sLmMuKhuNuxFBvu4bbcHwuL/5ccLQNlABk4luEi/7TFGovKfZMpT8CTBu7VsfSs6k6ebP4m0+lvrZeJP90Z9K4xmE4ZtdFGWHah3XYFZZykLDQZ6EC4gfRBBIJDF574h0M8XKZVntepdWkf6cXkCkeVkkIdzl3R7PsrapPDVSKJC+1/jnJtgknOsP5v1q/JGE0m0AGQxnHCjII+mt8NthZ6zrLCrj9J5oxnmjVyY7LKV+BY1bZxo3sLw29d8ToISX4bRELmwPu1XKs/1HUrhF6weMsP/WRAAZTlb01xIBs2gB1DtT4r0CJ+gcYztQ8vyAxS/iMfJsoU23EuF7A3aTw2JWKIuvL9a8W+iATPpv31nVktq3PAJpd7n8OJUhISG0g/NJrZia4Kexu1QUpOhu5HA49VrS6vSLMA1kQ5mi9uqQVFLc/FUcBbbZ3DiUjxrM6xNh0A5ijvDUMNPFzmRKdO8tKJR1HClhxREGwZ3UP5Lp2ZsxAvgZEfOwSNiTO84VllZwLLcEoubzmcT0qnBHJHdUeTVp+Qcb3gSsvogOlgTW2D+NjINxwsKl3yBO5ohZWhgjETBVuEiO97BAEH9FaNxDbbPnX4tfZEneIGeWJwojULaKgyUsPRa9VhVhs32f62/cieDexxKVk5gB+SnUHgRfPsLcjBereVbq8L/jh X-OriginatorOrg: wdc.com X-MS-Exchange-CrossTenant-Network-Message-Id: 8581a0a7-ebb9-48ef-72c6-08d981abf835 X-MS-Exchange-CrossTenant-AuthSource: CO6PR04MB7812.namprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 27 Sep 2021 11:43:05.6564 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: b61c8803-16f3-4c35-9b17-6f65f441df86 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: KhsoajUkTwDdRcC/dyCSdGRPFkOf2Mq2/jDbLSRzAbgjuY5ExudhZYjtc4M5vwfZ909cuwZCgwc8dkp378HmQg== X-MS-Exchange-Transport-CrossTenantHeadersStamped: CO6PR04MB7841 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org The kernel KVM RISC-V module will forward certain SBI calls to user space. These forwared SBI calls will usually be the SBI calls which cannot be emulated in kernel space such as PUTCHAR and GETCHAR calls. This patch extends kvm_cpu__handle_exit() to handle SBI calls forwarded to user space. Signed-off-by: Atish Patra Signed-off-by: Anup Patel --- riscv/include/kvm/sbi.h | 48 ++++++++++++++++++++++++++++++++++++++++ riscv/kvm-cpu.c | 49 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 riscv/include/kvm/sbi.h diff --git a/riscv/include/kvm/sbi.h b/riscv/include/kvm/sbi.h new file mode 100644 index 0000000..f4b4182 --- /dev/null +++ b/riscv/include/kvm/sbi.h @@ -0,0 +1,48 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Common SBI related defines and macros to be used by RISC-V kernel, + * RISC-V KVM and userspace. + * + * Copyright (c) 2019 Western Digital Corporation or its affiliates. + */ + +#ifndef __RISCV_SBI_H__ +#define __RISCV_SBI_H__ + +enum sbi_ext_id { + SBI_EXT_0_1_SET_TIMER = 0x0, + SBI_EXT_0_1_CONSOLE_PUTCHAR = 0x1, + SBI_EXT_0_1_CONSOLE_GETCHAR = 0x2, + SBI_EXT_0_1_CLEAR_IPI = 0x3, + SBI_EXT_0_1_SEND_IPI = 0x4, + SBI_EXT_0_1_REMOTE_FENCE_I = 0x5, + SBI_EXT_0_1_REMOTE_SFENCE_VMA = 0x6, + SBI_EXT_0_1_REMOTE_SFENCE_VMA_ASID = 0x7, + SBI_EXT_0_1_SHUTDOWN = 0x8, + SBI_EXT_BASE = 0x10, +}; + +enum sbi_ext_base_fid { + SBI_BASE_GET_SPEC_VERSION = 0, + SBI_BASE_GET_IMP_ID, + SBI_BASE_GET_IMP_VERSION, + SBI_BASE_PROBE_EXT, + SBI_BASE_GET_MVENDORID, + SBI_BASE_GET_MARCHID, + SBI_BASE_GET_MIMPID, +}; + +#define SBI_SPEC_VERSION_DEFAULT 0x1 +#define SBI_SPEC_VERSION_MAJOR_OFFSET 24 +#define SBI_SPEC_VERSION_MAJOR_MASK 0x7f +#define SBI_SPEC_VERSION_MINOR_MASK 0xffffff + +/* SBI return error codes */ +#define SBI_SUCCESS 0 +#define SBI_ERR_FAILURE -1 +#define SBI_ERR_NOT_SUPPORTED -2 +#define SBI_ERR_INVALID_PARAM -3 +#define SBI_ERR_DENIED -4 +#define SBI_ERR_INVALID_ADDRESS -5 + +#endif diff --git a/riscv/kvm-cpu.c b/riscv/kvm-cpu.c index 8adaddd..df90c7b 100644 --- a/riscv/kvm-cpu.c +++ b/riscv/kvm-cpu.c @@ -1,6 +1,7 @@ #include "kvm/kvm-cpu.h" #include "kvm/kvm.h" #include "kvm/virtio.h" +#include "kvm/sbi.h" #include "kvm/term.h" #include @@ -110,9 +111,55 @@ void kvm_cpu__delete(struct kvm_cpu *vcpu) free(vcpu); } +static bool kvm_cpu_riscv_sbi(struct kvm_cpu *vcpu) +{ + char ch; + bool ret = true; + int dfd = kvm_cpu__get_debug_fd(); + + switch (vcpu->kvm_run->riscv_sbi.extension_id) { + case SBI_EXT_0_1_CONSOLE_PUTCHAR: + ch = vcpu->kvm_run->riscv_sbi.args[0]; + term_putc(&ch, 1, 0); + vcpu->kvm_run->riscv_sbi.ret[0] = 0; + break; + case SBI_EXT_0_1_CONSOLE_GETCHAR: + if (term_readable(0)) + vcpu->kvm_run->riscv_sbi.ret[0] = + term_getc(vcpu->kvm, 0); + else + vcpu->kvm_run->riscv_sbi.ret[0] = SBI_ERR_FAILURE; + break; + default: + dprintf(dfd, "Unhandled SBI call\n"); + dprintf(dfd, "extension_id=0x%lx function_id=0x%lx\n", + vcpu->kvm_run->riscv_sbi.extension_id, + vcpu->kvm_run->riscv_sbi.function_id); + dprintf(dfd, "args[0]=0x%lx args[1]=0x%lx\n", + vcpu->kvm_run->riscv_sbi.args[0], + vcpu->kvm_run->riscv_sbi.args[1]); + dprintf(dfd, "args[2]=0x%lx args[3]=0x%lx\n", + vcpu->kvm_run->riscv_sbi.args[2], + vcpu->kvm_run->riscv_sbi.args[3]); + dprintf(dfd, "args[4]=0x%lx args[5]=0x%lx\n", + vcpu->kvm_run->riscv_sbi.args[4], + vcpu->kvm_run->riscv_sbi.args[5]); + ret = false; + break; + }; + + return ret; +} + bool kvm_cpu__handle_exit(struct kvm_cpu *vcpu) { - /* TODO: */ + switch (vcpu->kvm_run->exit_reason) { + case KVM_EXIT_RISCV_SBI: + return kvm_cpu_riscv_sbi(vcpu); + default: + break; + }; + return false; } From patchwork Mon Sep 27 11:42:27 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anup Patel X-Patchwork-Id: 12519647 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 19E83C433EF for ; Mon, 27 Sep 2021 11:43:28 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 051F560F6C for ; Mon, 27 Sep 2021 11:43:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234330AbhI0LpE (ORCPT ); Mon, 27 Sep 2021 07:45:04 -0400 Received: from esa6.hgst.iphmx.com ([216.71.154.45]:36578 "EHLO esa6.hgst.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234325AbhI0Los (ORCPT ); Mon, 27 Sep 2021 07:44:48 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=wdc.com; i=@wdc.com; q=dns/txt; s=dkim.wdc.com; t=1632742991; x=1664278991; h=from:to:cc:subject:date:message-id:in-reply-to: references:content-transfer-encoding:mime-version; bh=+mK7vf0MuUd//RpadQ1Cp9Qt9FPwo6hzcQK8qWaUcHE=; b=R6YAuL570N0rJafYlQmbvytw0tCTzLVFUcvduJKnRWOJVTcUbFjgGjfP 8It00q+Fb4ZjV09mr+Zr9vlmVSJp4LAkeu0cLkQW3o3q20LnIVeaZTZf1 ZlwKDy8T9AywoHKrlE8ThYKAZo0/FJcjZjU+S2xvzvtXzPLRQsXYI1c6w Q9Sm8VqBe+wGA/InNcMJ8TArFXSgzxF6NlrzMh4VQxzbW8XugiFmjEu2U 1wUcGN75syOc2E7MAnitj275lbDExAp2mZ/HYdU9EUMrXY0jLxoGjMzOQ gJ0QUL5QLL5wsBUVP7xvkC+Cj3F2UuTtSbKB9jGe3orrxJMskXTfENTE6 Q==; X-IronPort-AV: E=Sophos;i="5.85,326,1624291200"; d="scan'208";a="181673183" Received: from mail-bn8nam08lp2043.outbound.protection.outlook.com (HELO NAM04-BN8-obe.outbound.protection.outlook.com) ([104.47.74.43]) by ob1.hgst.iphmx.com with ESMTP; 27 Sep 2021 19:43:10 +0800 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=GXLeJ64lAp3Q3hp7jmIsbh27xC9cJLM+jf52AIY1L+/d/4tl2v4jg74sYvKACXcZ2DJlsbZV9eSJQgPza1sRgw8JYMooyLkb3cT0rOhHQmM9Z+4AI+PrKJCHy8wFjAeprUJJzgWUIdlajA4MM579yJ3O8/nHqGCOe/aSy8RS+ZNO6cQMFUINYloLVJ2o5QZgTF8YqJqM1geQuFBUQEe42dDjwwLBU7DEqcU2v1uEoR8RVp3eFF+3mCvWCl2bf14VAPCh7zxGzPnuCGqUF7VNht56Bb+ylcNQt3JQYP/7jlnOqtR2vjbl6RzztFUJlrPxCIoAfXpE17CHG5M8aCwFNg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=5eyFMlTJnJUUIedmzywRGS5GenL0J9FU5n4+qKN+g1c=; b=jmzom+m+IMBDrTJvhNAcHu2vMdli4Zc7luB6WSX5LKkPykNDmG5zQcIkOYTBxjI+WTmcklPA/6qCqsDFbW6Tf/mjJMfj9VBO4I1AdmrWiSSlekdMXzUSTihNFPztiajiEBaBYxfziUvGVEYTLQXmi6VJMeprdDBJowEvm5VB2N77OVILagJzjpBL9RtxliB94wuLQNuie3xsD4JjO1zfXio9/MUyoprbu647TvDDvW+qsKIuFFSGlmiKKd39xWePvBwZNJZJl6RE+buAKyZfE44L7d/NGNFlZb1aYg9no6Nyp+3Vq/fr1e7mxgS+/SV+RVV96c0C6we0unzbK2HSSQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=wdc.com; dmarc=pass action=none header.from=wdc.com; dkim=pass header.d=wdc.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sharedspace.onmicrosoft.com; s=selector2-sharedspace-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=5eyFMlTJnJUUIedmzywRGS5GenL0J9FU5n4+qKN+g1c=; b=AztxHmSKdLvJ0I/i//BkM8XWGhB2xQwOwH/6eFJ688WwWpIB3NAAUdWsrhx28YZRcJmPN8hlnCtE5wcYi/r5WHmPrRmcT4FmFIyyhTBY6KN3pMvdnFIbVJE1OJYYQ5UdFIcGfPSAdYf+5UT+KcR6INDkOPY2DRXDb3ggibIfGak= Authentication-Results: kernel.org; dkim=none (message not signed) header.d=none;kernel.org; dmarc=none action=none header.from=wdc.com; Received: from CO6PR04MB7812.namprd04.prod.outlook.com (2603:10b6:303:138::6) by CO6PR04MB7841.namprd04.prod.outlook.com (2603:10b6:5:358::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4544.13; Mon, 27 Sep 2021 11:43:08 +0000 Received: from CO6PR04MB7812.namprd04.prod.outlook.com ([fe80::6830:650b:8265:af0b]) by CO6PR04MB7812.namprd04.prod.outlook.com ([fe80::6830:650b:8265:af0b%6]) with mapi id 15.20.4544.021; Mon, 27 Sep 2021 11:43:08 +0000 From: Anup Patel To: Will Deacon Cc: Paolo Bonzini , Atish Patra , Alistair Francis , Anup Patel , kvm@vger.kernel.org, kvm-riscv@lists.infradead.org, Anup Patel Subject: [PATCH v9 8/8] riscv: Generate PCI host DT node Date: Mon, 27 Sep 2021 17:12:27 +0530 Message-Id: <20210927114227.1089403-9-anup.patel@wdc.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210927114227.1089403-1-anup.patel@wdc.com> References: <20210927114227.1089403-1-anup.patel@wdc.com> X-ClientProxiedBy: MA1PR01CA0173.INDPRD01.PROD.OUTLOOK.COM (2603:1096:a01:d::14) To CO6PR04MB7812.namprd04.prod.outlook.com (2603:10b6:303:138::6) MIME-Version: 1.0 Received: from wdc.com (122.179.75.205) by MA1PR01CA0173.INDPRD01.PROD.OUTLOOK.COM (2603:1096:a01:d::14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4544.14 via Frontend Transport; Mon, 27 Sep 2021 11:43:06 +0000 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: f64d9363-3b21-49bd-50fb-08d981abf9d6 X-MS-TrafficTypeDiagnostic: CO6PR04MB7841: X-MS-Exchange-Transport-Forked: True X-Microsoft-Antispam-PRVS: WDCIPOUTBOUND: EOP-TRUE X-MS-Oob-TLC-OOBClassifiers: OLM:6108; X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: 2KrLgE75Tw3bh3MicPV15xBqpSEBV5ovZNajXqaq2DnuPMQERA1HokSamlKGGDUs2cM0iCy4Etxos+RzbIaJprNf22X90lg3RN8/p2tGGNlyJUubj45ur10Pew8ajM9ap2DXfVGBC5tWyzIbxgadKtrKMCEIqGsbo4YxmrhofeWKFx2u5Q32epBIxmxAhH/6Tv81HNyr+rzR/+5yl+i/FeIRRMvbew9H2a8YPjBC+6lZOfuviFRzO7V5HqvpXTd5t1VVHBuaE3gfUiWvpADXhYJrWzTVbca1H/qJUQrogqX8pTCZFX8Zrnbk61h9O+7mFqiwWS0PvSv7At4XIceJrZD3SDAcBMAhYGGqqu5vWnDuJCj8BP+n79TaCKnC/6nJh0GM6wHr2kvJ4cvG269UqmMYotKAhF6mFpVw463wACzGJxV8L1VTqn75LxIwXKpQO4+mlZGSNBqmCp7TWfqxvKMrp/7Zn9RVgHFybBKFbr8fZ713NR+Ryb/NzQJdPF0o2jI6n59qiIUPnUjK8wY2wXpP2DLSTrl1L3KxbCGq0pU4G/tBvxnNxqICGTywTdwJIeIjJKQb/7W/I46pzP35spQDWw5K8E5U3fhnB8dGHi2O/v7hiUhROXNn4qmhGNRrGdK1kT4Klhar+kl3/EOwfYnZed0vI1JI4yiFXwTM2zQr07GsHzxkd1c7fL6oQXuD X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:CO6PR04MB7812.namprd04.prod.outlook.com;PTR:;CAT:NONE;SFS:(4636009)(366004)(54906003)(316002)(5660300002)(1076003)(66556008)(66946007)(66476007)(36756003)(38100700002)(38350700002)(55016002)(86362001)(508600001)(6916009)(44832011)(8886007)(6666004)(2906002)(8676002)(956004)(2616005)(7696005)(8936002)(4326008)(26005)(52116002)(186003);DIR:OUT;SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: JrS+kTnJktbYAQlCQgYD/baYuxE6Kt+0D60DV9YE97m12wPCz8Wo0gZGHOUMw3QDLs566l8YCPpMo7MnnVkJvy7p+ZlR9KsqY7Cd3cJD6Np/QekXKPqRIbxCq0KlqsCksmkek4XpWzY03Yjh8m0wN55GojAmHy4630uXdGS/ORQ3USyU4U8ExNxArDAbzmxjM5yB0IOC3b7pk05fS0KiaPthl8erLlwRrmPJVOOFmgrrpQRQxbSSITbJTF7R5gt0IUrRONKcPOYqwexpBIqrjOR1n4oxq29ai5XgSmM1zDHKPSmEnWwPzsbb4KvaF4d9vB8kUROdSag8G4yNBXD59/vG3rhaAO7aF/rokQCva8t6T+1xB455HEdE2/sWgw9Ru+iEy7X2P7QehYlOk3FOlRy9WnjCYfU+iQSLb539SEzAXAS032F6mtBBTigfZUmhlDd0qKpYmFMx1l3hgXGNT9IkejuwTGJ2iXoe5LjfNEljHpjObfnW+IBX5TGreIVGN5dgLZV7enhRzRa/paebH8i6TagBjTPvPyI1xDKIE6J1pFNzI7aLMsgGOZq5h2/DIR6vMK0tje5SPzFwrAXbyPEkevT5QgY8g5M4cP4G7NutpeQtJr42LH+4NlyBuZn2vlgLILzfU7xbahP68gCAySfdEo80Qs/87W+XvSXauarFHecn+maqcyTw2OFkMlJxrvB9JtTHE+ZxucGpmXO23ZTIkoNfsw9/kJGccFwbEDODIT47/qbpobcbhp5ZQa+ssKmouDvBTtelcN7bgi50WrTg+Mg5xR/cG4SSf2ZlD1jzrbNg+Zpif0OhOlxBPpuA3HsT+/stvnEfprokoorzEL+BnGm9s4nEE4XtAn8DVbMxU5nrAKNaMuGimo/SdqwsgDMqa7LzzkunqnCYd7P8ti7EBaTXmiTT2o1baY3n3ChfqPmvvRf+TY0LzaQQbQeDgQdfZlAD8EOtLeJkCz/e3K8ZeMNE0bcp21vGmL8H/xNtVX6BmMR9CJ+ojyNsw4ld5kj91GhNwvtljfq6Jjf5kGXL9sHY/JozWVxzFnvdfpD73IP2FWRCCgsLKpZMfkce6fUCOAHNPhHEYfwNTZskSeVBf0N2fYkWSxYgw0ym5B15UlunzRB5tseCHwnuVLo/s5lc98dr9dcOxemajqLyww9bjghHPhSUGuS9dkoh7vVzc16FHMWGmfHPotn7lITzsNBgZ5TH17GvBQNVuh1VV7WGBWzkXWdG74NZ2Tyzk/J5iWTaKM1mILttUv/cu6O6TEz6OLGQxvRNu/Chi2FOG2OmF/XJzTNqeVFXN2tPySJR2Hm8C/JtvjG03p9aw92O X-OriginatorOrg: wdc.com X-MS-Exchange-CrossTenant-Network-Message-Id: f64d9363-3b21-49bd-50fb-08d981abf9d6 X-MS-Exchange-CrossTenant-AuthSource: CO6PR04MB7812.namprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 27 Sep 2021 11:43:08.2082 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: b61c8803-16f3-4c35-9b17-6f65f441df86 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: Qhex0WGMqCPagSnmFGiIM1T9SfX0idWK8XXtzafRMcTUq74catHy9xqZZVroCOl4KoJ5rrEuLVSCwLiaje8fmg== X-MS-Exchange-Transport-CrossTenantHeadersStamped: CO6PR04MB7841 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org This patch extends FDT generation to generate PCI host DT node. Of course, PCI host for Guest/VM is not useful at the moment because it's mostly for PCI pass-through and we don't have IOMMU and interrupt routing available for KVM RISC-V. In future, we might be able to use PCI host for VirtIO PCI transport or other software emulated PCI devices. Signed-off-by: Anup Patel --- Makefile | 1 + riscv/fdt.c | 3 + riscv/include/kvm/kvm-arch.h | 2 + riscv/pci.c | 109 +++++++++++++++++++++++++++++++++++ 4 files changed, 115 insertions(+) create mode 100644 riscv/pci.c diff --git a/Makefile b/Makefile index e4e1184..6920d7f 100644 --- a/Makefile +++ b/Makefile @@ -204,6 +204,7 @@ ifeq ($(ARCH),riscv) OBJS += riscv/irq.o OBJS += riscv/kvm.o OBJS += riscv/kvm-cpu.o + OBJS += riscv/pci.o OBJS += riscv/plic.o ifeq ($(RISCV_XLEN),32) CFLAGS += -mabi=ilp32d -march=rv32gc diff --git a/riscv/fdt.c b/riscv/fdt.c index 6527ef7..de15bfe 100644 --- a/riscv/fdt.c +++ b/riscv/fdt.c @@ -167,6 +167,9 @@ static int setup_fdt(struct kvm *kvm) dev_hdr = device__next_dev(dev_hdr); } + /* PCI host controller */ + pci__generate_fdt_nodes(fdt); + _FDT(fdt_end_node(fdt)); if (fdt_stdout_path) { diff --git a/riscv/include/kvm/kvm-arch.h b/riscv/include/kvm/kvm-arch.h index 884c16b..a6dd0fe 100644 --- a/riscv/include/kvm/kvm-arch.h +++ b/riscv/include/kvm/kvm-arch.h @@ -82,4 +82,6 @@ void plic__generate_irq_prop(void *fdt, u8 irq, enum irq_type irq_type); void plic__irq_trig(struct kvm *kvm, int irq, int level, bool edge); +void pci__generate_fdt_nodes(void *fdt); + #endif /* KVM__KVM_ARCH_H */ diff --git a/riscv/pci.c b/riscv/pci.c new file mode 100644 index 0000000..604fd20 --- /dev/null +++ b/riscv/pci.c @@ -0,0 +1,109 @@ +#include "kvm/devices.h" +#include "kvm/fdt.h" +#include "kvm/kvm.h" +#include "kvm/of_pci.h" +#include "kvm/pci.h" +#include "kvm/util.h" + +/* + * An entry in the interrupt-map table looks like: + * + */ + +struct of_interrupt_map_entry { + struct of_pci_irq_mask pci_irq_mask; + u32 plic_phandle; + u32 plic_irq; +} __attribute__((packed)); + +void pci__generate_fdt_nodes(void *fdt) +{ + struct device_header *dev_hdr; + struct of_interrupt_map_entry irq_map[OF_PCI_IRQ_MAP_MAX]; + unsigned nentries = 0; + /* Bus range */ + u32 bus_range[] = { cpu_to_fdt32(0), cpu_to_fdt32(1), }; + /* Configuration Space */ + u64 cfg_reg_prop[] = { cpu_to_fdt64(KVM_PCI_CFG_AREA), + cpu_to_fdt64(RISCV_PCI_CFG_SIZE), }; + /* Describe the memory ranges */ + struct of_pci_ranges_entry ranges[] = { + { + .pci_addr = { + .hi = cpu_to_fdt32(of_pci_b_ss(OF_PCI_SS_IO)), + .mid = 0, + .lo = 0, + }, + .cpu_addr = cpu_to_fdt64(KVM_IOPORT_AREA), + .length = cpu_to_fdt64(RISCV_IOPORT_SIZE), + }, + { + .pci_addr = { + .hi = cpu_to_fdt32(of_pci_b_ss(OF_PCI_SS_M32)), + .mid = cpu_to_fdt32(KVM_PCI_MMIO_AREA >> 32), + .lo = cpu_to_fdt32(KVM_PCI_MMIO_AREA), + }, + .cpu_addr = cpu_to_fdt64(KVM_PCI_MMIO_AREA), + .length = cpu_to_fdt64(RISCV_PCI_MMIO_SIZE), + }, + }; + + /* Boilerplate PCI properties */ + _FDT(fdt_begin_node(fdt, "pci")); + _FDT(fdt_property_string(fdt, "device_type", "pci")); + _FDT(fdt_property_cell(fdt, "#address-cells", 0x3)); + _FDT(fdt_property_cell(fdt, "#size-cells", 0x2)); + _FDT(fdt_property_cell(fdt, "#interrupt-cells", 0x1)); + _FDT(fdt_property_string(fdt, "compatible", "pci-host-ecam-generic")); + _FDT(fdt_property(fdt, "dma-coherent", NULL, 0)); + + _FDT(fdt_property(fdt, "bus-range", bus_range, sizeof(bus_range))); + _FDT(fdt_property(fdt, "reg", &cfg_reg_prop, sizeof(cfg_reg_prop))); + _FDT(fdt_property(fdt, "ranges", ranges, sizeof(ranges))); + + /* Generate the interrupt map ... */ + dev_hdr = device__first_dev(DEVICE_BUS_PCI); + while (dev_hdr && nentries < ARRAY_SIZE(irq_map)) { + struct of_interrupt_map_entry *entry = &irq_map[nentries]; + struct pci_device_header *pci_hdr = dev_hdr->data; + u8 dev_num = dev_hdr->dev_num; + u8 pin = pci_hdr->irq_pin; + u8 irq = pci_hdr->irq_line; + + *entry = (struct of_interrupt_map_entry) { + .pci_irq_mask = { + .pci_addr = { + .hi = cpu_to_fdt32(of_pci_b_ddddd(dev_num)), + .mid = 0, + .lo = 0, + }, + .pci_pin = cpu_to_fdt32(pin), + }, + .plic_phandle = cpu_to_fdt32(PHANDLE_PLIC), + .plic_irq = cpu_to_fdt32(irq), + }; + + nentries++; + dev_hdr = device__next_dev(dev_hdr); + } + + _FDT(fdt_property(fdt, "interrupt-map", irq_map, + sizeof(struct of_interrupt_map_entry) * nentries)); + + /* ... and the corresponding mask. */ + if (nentries) { + struct of_pci_irq_mask irq_mask = { + .pci_addr = { + .hi = cpu_to_fdt32(of_pci_b_ddddd(-1)), + .mid = 0, + .lo = 0, + }, + .pci_pin = cpu_to_fdt32(7), + }; + + _FDT(fdt_property(fdt, "interrupt-map-mask", &irq_mask, + sizeof(irq_mask))); + } + + _FDT(fdt_end_node(fdt)); +}