From patchwork Tue Aug 1 22:26:21 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Henrique Barboza X-Patchwork-Id: 13337317 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 bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id A0FCDC04A6A for ; Tue, 1 Aug 2023 22:26:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=kwxakJiQre9zJRr/1fdowmdz+upL4bUNwt/t+OmtTW4=; b=45UQoltkVp+3mz 6QAsjOHMnydsHRM0tflIeBn9R3Ml63onYo1lkPwNVEjgt4u+aFIUrnEUqSkn51DV6eN4QvcqR+e9X rQRuEhEljnbf6UgQjn+jxlcHMSsKrjQDq9Ab3qeX8kC7a2R5s+opUxef5hkagbtRYbGx4YpwHxcuL gQmjqP74lvzi0ZAbbiukMqI1p2mRbz72Py0EnyAKpkxtejtLUdpRE8dJnXY5koLSySBRNI48G3A+D kpl6ogMFKO1w5M9t2UomuZCs71QIyIBWd4GD0hTD7ffQGgdgljHqrBkEgGZkT1FDQElG8nLCrTyd/ w8TOf2UQZWpNBI+iLQ5w==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1qQxpD-003QoG-0Q; Tue, 01 Aug 2023 22:26:43 +0000 Received: from mail-ot1-x32c.google.com ([2607:f8b0:4864:20::32c]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1qQxp9-003Qm3-2n for linux-riscv@lists.infradead.org; Tue, 01 Aug 2023 22:26:41 +0000 Received: by mail-ot1-x32c.google.com with SMTP id 46e09a7af769-6bcaa6d5e2cso1804107a34.3 for ; Tue, 01 Aug 2023 15:26:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ventanamicro.com; s=google; t=1690928798; x=1691533598; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=uTY/0Vp4+EKuNn4o6K47a7dBtdu0fgPSmf1UiI9M0QQ=; b=H5sTSbLSsY38uPl4OrHzut+lKswxTFaZI2TRjOb9l9PQ7sAgPSqWVPUzoNqAJYiAYK 2Up/BqMW0W//Fbhk+hYHD8jZffd11hL6Lhf5ScXkUU5LfOlhT151q9Nox+6H0DMGrz3q m/10/PiFaLEsxdi1VN153rIz7BWLPHub42NIRENl5YuKTBaZBmIK2jxFIa3SPfRVUg6S eKkSLC6dzqH0M52GuspEfaVQ1NARK4w45+lEFWWw6M744Ou2XQ0vglAYFVTe/iAARPv1 FnUFwy8tSUQZRiGMMoMc8UNlzWVibR0kk85mNAFVxaZawrN60dcjpTIRghiOH6kFCyh6 9cFg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1690928798; x=1691533598; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=uTY/0Vp4+EKuNn4o6K47a7dBtdu0fgPSmf1UiI9M0QQ=; b=N/DptoZDj86KYmqPBpp9Lh982hJsSr5h+WU1Du5yoNdhaRwrET+bf7LP36GYtsoAwa ba8VEAIr9WPRzPZukO4oGPgwRISbHcJXFFQKY7kVnk7aucNX0P/id6yAWRYjeoUR64r6 0jB23l/OKP0v/8DN7p83WV2d1h73BSzHdiiyDyw8NnEXPVORevzgt6hzw+8m0U/2m11V yf9W8BI9kal3FDrZ5IYq1rmsqZHNBxVini9mUrVYkNv/9k1zPSK4Dvk7Bos7bTD6tHpo gKLdUgirW4rEpyf/IA2z0mQ80qydaRph2obU+PrKFngR2XzBfPctDj0i0tUC8brYrawU giYg== X-Gm-Message-State: ABy/qLYbzljVEfnVgg/rfuSZmEJUdEGrbmJ0yr8BdLcCqL8DoM5+9ONW VHj+MvohQquWfoBRL0ZFxC2zhg== X-Google-Smtp-Source: APBJJlGhPOgUgGjapcb6GhDCXXm+Ugm82pu3zLudoWYBEtCzG1rr/HqBAMR1W69NgNBLVeY04QHIFw== X-Received: by 2002:a05:6871:10c:b0:1b0:3cd4:76d5 with SMTP id y12-20020a056871010c00b001b03cd476d5mr15772488oab.37.1690928797984; Tue, 01 Aug 2023 15:26:37 -0700 (PDT) Received: from grind.. ([187.11.154.63]) by smtp.gmail.com with ESMTPSA id e15-20020a9d6e0f000000b006b94904baf5sm5422429otr.74.2023.08.01.15.26.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Aug 2023 15:26:37 -0700 (PDT) From: Daniel Henrique Barboza To: kvm-riscv@lists.infradead.org, linux-riscv@lists.infradead.org, kvm@vger.kernel.org Cc: anup@brainfault.org, atishp@atishpatra.org, ajones@ventanamicro.com, Daniel Henrique Barboza Subject: [PATCH v2 1/9] RISC-V: KVM: return ENOENT in *_one_reg() when reg is unknown Date: Tue, 1 Aug 2023 19:26:21 -0300 Message-ID: <20230801222629.210929-2-dbarboza@ventanamicro.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230801222629.210929-1-dbarboza@ventanamicro.com> References: <20230801222629.210929-1-dbarboza@ventanamicro.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230801_152639_905520_A030FBFB X-CRM114-Status: GOOD ( 20.33 ) X-BeenThere: linux-riscv@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-riscv" Errors-To: linux-riscv-bounces+linux-riscv=archiver.kernel.org@lists.infradead.org get_one_reg() and set_one_reg() are returning EINVAL errors for almost everything: if a reg doesn't exist, if a reg ID is malformatted, if the associated CPU extension that implements the reg isn't present in the host, and for set_one_reg() if the value being written is invalid. This isn't wrong according to the existing KVM API docs (EINVAL can be used when there's no such register) but adding more ENOENT instances will make easier for userspace to understand what went wrong. Existing userspaces can be affected by this error code change. We checked a few. As of current upstream code, crosvm doesn't check for any particular errno code when using kvm_(get|set)_one_reg(). Neither does QEMU. rust-vmm doesn't have kvm-riscv support yet. Thus we have a good chance of changing these error codes now while the KVM RISC-V ecosystem is still new, minimizing user impact. Change all get_one_reg() and set_one_reg() implementations to return -ENOENT at all "no such register" cases. Signed-off-by: Daniel Henrique Barboza --- arch/riscv/kvm/aia.c | 4 ++-- arch/riscv/kvm/vcpu_fp.c | 12 ++++++------ arch/riscv/kvm/vcpu_onereg.c | 30 +++++++++++++++--------------- arch/riscv/kvm/vcpu_sbi.c | 16 +++++++++------- arch/riscv/kvm/vcpu_timer.c | 8 ++++---- 5 files changed, 36 insertions(+), 34 deletions(-) diff --git a/arch/riscv/kvm/aia.c b/arch/riscv/kvm/aia.c index 585a3b42c52c..74bb27440527 100644 --- a/arch/riscv/kvm/aia.c +++ b/arch/riscv/kvm/aia.c @@ -176,7 +176,7 @@ int kvm_riscv_vcpu_aia_get_csr(struct kvm_vcpu *vcpu, struct kvm_vcpu_aia_csr *csr = &vcpu->arch.aia_context.guest_csr; if (reg_num >= sizeof(struct kvm_riscv_aia_csr) / sizeof(unsigned long)) - return -EINVAL; + return -ENOENT; *out_val = 0; if (kvm_riscv_aia_available()) @@ -192,7 +192,7 @@ int kvm_riscv_vcpu_aia_set_csr(struct kvm_vcpu *vcpu, struct kvm_vcpu_aia_csr *csr = &vcpu->arch.aia_context.guest_csr; if (reg_num >= sizeof(struct kvm_riscv_aia_csr) / sizeof(unsigned long)) - return -EINVAL; + return -ENOENT; if (kvm_riscv_aia_available()) { ((unsigned long *)csr)[reg_num] = val; diff --git a/arch/riscv/kvm/vcpu_fp.c b/arch/riscv/kvm/vcpu_fp.c index 9d8cbc42057a..08ba48a395aa 100644 --- a/arch/riscv/kvm/vcpu_fp.c +++ b/arch/riscv/kvm/vcpu_fp.c @@ -96,7 +96,7 @@ int kvm_riscv_vcpu_get_reg_fp(struct kvm_vcpu *vcpu, reg_num <= KVM_REG_RISCV_FP_F_REG(f[31])) reg_val = &cntx->fp.f.f[reg_num]; else - return -EINVAL; + return -ENOENT; } else if ((rtype == KVM_REG_RISCV_FP_D) && riscv_isa_extension_available(vcpu->arch.isa, d)) { if (reg_num == KVM_REG_RISCV_FP_D_REG(fcsr)) { @@ -109,9 +109,9 @@ int kvm_riscv_vcpu_get_reg_fp(struct kvm_vcpu *vcpu, return -EINVAL; reg_val = &cntx->fp.d.f[reg_num]; } else - return -EINVAL; + return -ENOENT; } else - return -EINVAL; + return -ENOENT; if (copy_to_user(uaddr, reg_val, KVM_REG_SIZE(reg->id))) return -EFAULT; @@ -141,7 +141,7 @@ int kvm_riscv_vcpu_set_reg_fp(struct kvm_vcpu *vcpu, reg_num <= KVM_REG_RISCV_FP_F_REG(f[31])) reg_val = &cntx->fp.f.f[reg_num]; else - return -EINVAL; + return -ENOENT; } else if ((rtype == KVM_REG_RISCV_FP_D) && riscv_isa_extension_available(vcpu->arch.isa, d)) { if (reg_num == KVM_REG_RISCV_FP_D_REG(fcsr)) { @@ -154,9 +154,9 @@ int kvm_riscv_vcpu_set_reg_fp(struct kvm_vcpu *vcpu, return -EINVAL; reg_val = &cntx->fp.d.f[reg_num]; } else - return -EINVAL; + return -ENOENT; } else - return -EINVAL; + return -ENOENT; if (copy_from_user(reg_val, uaddr, KVM_REG_SIZE(reg->id))) return -EFAULT; diff --git a/arch/riscv/kvm/vcpu_onereg.c b/arch/riscv/kvm/vcpu_onereg.c index 0dc2c2cecb45..ba63522be060 100644 --- a/arch/riscv/kvm/vcpu_onereg.c +++ b/arch/riscv/kvm/vcpu_onereg.c @@ -153,7 +153,7 @@ static int kvm_riscv_vcpu_get_reg_config(struct kvm_vcpu *vcpu, reg_val = vcpu->arch.mimpid; break; default: - return -EINVAL; + return -ENOENT; } if (copy_to_user(uaddr, ®_val, KVM_REG_SIZE(reg->id))) @@ -235,7 +235,7 @@ static int kvm_riscv_vcpu_set_reg_config(struct kvm_vcpu *vcpu, return -EBUSY; break; default: - return -EINVAL; + return -ENOENT; } return 0; @@ -255,7 +255,7 @@ static int kvm_riscv_vcpu_get_reg_core(struct kvm_vcpu *vcpu, if (KVM_REG_SIZE(reg->id) != sizeof(unsigned long)) return -EINVAL; if (reg_num >= sizeof(struct kvm_riscv_core) / sizeof(unsigned long)) - return -EINVAL; + return -ENOENT; if (reg_num == KVM_REG_RISCV_CORE_REG(regs.pc)) reg_val = cntx->sepc; @@ -266,7 +266,7 @@ static int kvm_riscv_vcpu_get_reg_core(struct kvm_vcpu *vcpu, reg_val = (cntx->sstatus & SR_SPP) ? KVM_RISCV_MODE_S : KVM_RISCV_MODE_U; else - return -EINVAL; + return -ENOENT; if (copy_to_user(uaddr, ®_val, KVM_REG_SIZE(reg->id))) return -EFAULT; @@ -288,7 +288,7 @@ static int kvm_riscv_vcpu_set_reg_core(struct kvm_vcpu *vcpu, if (KVM_REG_SIZE(reg->id) != sizeof(unsigned long)) return -EINVAL; if (reg_num >= sizeof(struct kvm_riscv_core) / sizeof(unsigned long)) - return -EINVAL; + return -ENOENT; if (copy_from_user(®_val, uaddr, KVM_REG_SIZE(reg->id))) return -EFAULT; @@ -304,7 +304,7 @@ static int kvm_riscv_vcpu_set_reg_core(struct kvm_vcpu *vcpu, else cntx->sstatus &= ~SR_SPP; } else - return -EINVAL; + return -ENOENT; return 0; } @@ -316,7 +316,7 @@ static int kvm_riscv_vcpu_general_get_csr(struct kvm_vcpu *vcpu, struct kvm_vcpu_csr *csr = &vcpu->arch.guest_csr; if (reg_num >= sizeof(struct kvm_riscv_csr) / sizeof(unsigned long)) - return -EINVAL; + return -ENOENT; if (reg_num == KVM_REG_RISCV_CSR_REG(sip)) { kvm_riscv_vcpu_flush_interrupts(vcpu); @@ -335,7 +335,7 @@ static int kvm_riscv_vcpu_general_set_csr(struct kvm_vcpu *vcpu, struct kvm_vcpu_csr *csr = &vcpu->arch.guest_csr; if (reg_num >= sizeof(struct kvm_riscv_csr) / sizeof(unsigned long)) - return -EINVAL; + return -ENOENT; if (reg_num == KVM_REG_RISCV_CSR_REG(sip)) { reg_val &= VSIP_VALID_MASK; @@ -374,7 +374,7 @@ static int kvm_riscv_vcpu_get_reg_csr(struct kvm_vcpu *vcpu, rc = kvm_riscv_vcpu_aia_get_csr(vcpu, reg_num, ®_val); break; default: - rc = -EINVAL; + rc = -ENOENT; break; } if (rc) @@ -413,7 +413,7 @@ static int kvm_riscv_vcpu_set_reg_csr(struct kvm_vcpu *vcpu, rc = kvm_riscv_vcpu_aia_set_csr(vcpu, reg_num, reg_val); break; default: - rc = -EINVAL; + rc = -ENOENT; break; } if (rc) @@ -430,7 +430,7 @@ static int riscv_vcpu_get_isa_ext_single(struct kvm_vcpu *vcpu, if (reg_num >= KVM_RISCV_ISA_EXT_MAX || reg_num >= ARRAY_SIZE(kvm_isa_ext_arr)) - return -EINVAL; + return -ENOENT; *reg_val = 0; host_isa_ext = kvm_isa_ext_arr[reg_num]; @@ -448,7 +448,7 @@ static int riscv_vcpu_set_isa_ext_single(struct kvm_vcpu *vcpu, if (reg_num >= KVM_RISCV_ISA_EXT_MAX || reg_num >= ARRAY_SIZE(kvm_isa_ext_arr)) - return -EINVAL; + return -ENOENT; host_isa_ext = kvm_isa_ext_arr[reg_num]; if (!__riscv_isa_extension_available(NULL, host_isa_ext)) @@ -547,7 +547,7 @@ static int kvm_riscv_vcpu_get_reg_isa_ext(struct kvm_vcpu *vcpu, reg_val = ~reg_val; break; default: - rc = -EINVAL; + rc = -ENOENT; } if (rc) return rc; @@ -585,7 +585,7 @@ static int kvm_riscv_vcpu_set_reg_isa_ext(struct kvm_vcpu *vcpu, case KVM_REG_RISCV_SBI_MULTI_DIS: return riscv_vcpu_set_isa_ext_multi(vcpu, reg_num, reg_val, false); default: - return -EINVAL; + return -ENOENT; } return 0; @@ -652,5 +652,5 @@ int kvm_riscv_vcpu_get_reg(struct kvm_vcpu *vcpu, break; } - return -EINVAL; + return -ENOENT; } diff --git a/arch/riscv/kvm/vcpu_sbi.c b/arch/riscv/kvm/vcpu_sbi.c index 7b46e04fb667..9cd97091c723 100644 --- a/arch/riscv/kvm/vcpu_sbi.c +++ b/arch/riscv/kvm/vcpu_sbi.c @@ -140,8 +140,10 @@ static int riscv_vcpu_set_sbi_ext_single(struct kvm_vcpu *vcpu, const struct kvm_riscv_sbi_extension_entry *sext = NULL; struct kvm_vcpu_sbi_context *scontext = &vcpu->arch.sbi_context; - if (reg_num >= KVM_RISCV_SBI_EXT_MAX || - (reg_val != 1 && reg_val != 0)) + if (reg_num >= KVM_RISCV_SBI_EXT_MAX) + return -ENOENT; + + if (reg_val != 1 && reg_val != 0) return -EINVAL; for (i = 0; i < ARRAY_SIZE(sbi_ext); i++) { @@ -175,7 +177,7 @@ static int riscv_vcpu_get_sbi_ext_single(struct kvm_vcpu *vcpu, struct kvm_vcpu_sbi_context *scontext = &vcpu->arch.sbi_context; if (reg_num >= KVM_RISCV_SBI_EXT_MAX) - return -EINVAL; + return -ENOENT; for (i = 0; i < ARRAY_SIZE(sbi_ext); i++) { if (sbi_ext[i].ext_idx == reg_num) { @@ -206,7 +208,7 @@ static int riscv_vcpu_set_sbi_ext_multi(struct kvm_vcpu *vcpu, unsigned long i, ext_id; if (reg_num > KVM_REG_RISCV_SBI_MULTI_REG_LAST) - return -EINVAL; + return -ENOENT; for_each_set_bit(i, ®_val, BITS_PER_LONG) { ext_id = i + reg_num * BITS_PER_LONG; @@ -226,7 +228,7 @@ static int riscv_vcpu_get_sbi_ext_multi(struct kvm_vcpu *vcpu, unsigned long i, ext_id, ext_val; if (reg_num > KVM_REG_RISCV_SBI_MULTI_REG_LAST) - return -EINVAL; + return -ENOENT; for (i = 0; i < BITS_PER_LONG; i++) { ext_id = i + reg_num * BITS_PER_LONG; @@ -272,7 +274,7 @@ int kvm_riscv_vcpu_set_reg_sbi_ext(struct kvm_vcpu *vcpu, case KVM_REG_RISCV_SBI_MULTI_DIS: return riscv_vcpu_set_sbi_ext_multi(vcpu, reg_num, reg_val, false); default: - return -EINVAL; + return -ENOENT; } return 0; @@ -307,7 +309,7 @@ int kvm_riscv_vcpu_get_reg_sbi_ext(struct kvm_vcpu *vcpu, reg_val = ~reg_val; break; default: - rc = -EINVAL; + rc = -ENOENT; } if (rc) return rc; diff --git a/arch/riscv/kvm/vcpu_timer.c b/arch/riscv/kvm/vcpu_timer.c index 3ac2ff6a65da..527d269cafff 100644 --- a/arch/riscv/kvm/vcpu_timer.c +++ b/arch/riscv/kvm/vcpu_timer.c @@ -170,7 +170,7 @@ int kvm_riscv_vcpu_get_reg_timer(struct kvm_vcpu *vcpu, if (KVM_REG_SIZE(reg->id) != sizeof(u64)) return -EINVAL; if (reg_num >= sizeof(struct kvm_riscv_timer) / sizeof(u64)) - return -EINVAL; + return -ENOENT; switch (reg_num) { case KVM_REG_RISCV_TIMER_REG(frequency): @@ -187,7 +187,7 @@ int kvm_riscv_vcpu_get_reg_timer(struct kvm_vcpu *vcpu, KVM_RISCV_TIMER_STATE_OFF; break; default: - return -EINVAL; + return -ENOENT; } if (copy_to_user(uaddr, ®_val, KVM_REG_SIZE(reg->id))) @@ -211,7 +211,7 @@ int kvm_riscv_vcpu_set_reg_timer(struct kvm_vcpu *vcpu, if (KVM_REG_SIZE(reg->id) != sizeof(u64)) return -EINVAL; if (reg_num >= sizeof(struct kvm_riscv_timer) / sizeof(u64)) - return -EINVAL; + return -ENOENT; if (copy_from_user(®_val, uaddr, KVM_REG_SIZE(reg->id))) return -EFAULT; @@ -233,7 +233,7 @@ int kvm_riscv_vcpu_set_reg_timer(struct kvm_vcpu *vcpu, ret = kvm_riscv_vcpu_timer_cancel(t); break; default: - ret = -EINVAL; + ret = -ENOENT; break; }