From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-ej1-f72.google.com (mail-ej1-f72.google.com [209.85.218.72]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9E7EC4766A1 for ; Fri, 7 Aug 2026 16:43:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.72 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786121045; cv=none; b=JvVQJe+5dWYQ3Cv/mOz99j9QHUHav4wZBR8KXboaVkMauhl6hwnahXOuaUJzSTETfFTEje/DTfdFytTui89n4/MpQaMzAoN10TmweQ5jsP+T5Espy+8SWBzqVGn8ZZJyf1hUqoXXcPAFwmf6RAgKLWQJzwGWC+Bs//vHlzL/f98= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786121045; c=relaxed/simple; bh=evapBqF9fdH+H6PlBk1r5uqALms6dqHIsGbi9+k9YLk=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=JRq3gEdq8UEfCwboAzTrmPaGlTJNpGk5V30PLP+N3R51k6g+06oVDfGloaGRlUwSd8dvbdU/JgtP/DnGCcPYmZZXGYM5n41NiFtIvD2HG1pnTd6bq2DqRPuG8bHvXDBYwbSzn5Sy1PDsOQDeUzobbu2jEUx5JcMqkX4FAc45GKU= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--sebastianene.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=pn214yGD; arc=none smtp.client-ip=209.85.218.72 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--sebastianene.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="pn214yGD" Received: by mail-ej1-f72.google.com with SMTP id a640c23a62f3a-c1c232fa136so271842166b.0 for ; Fri, 07 Aug 2026 09:43:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1786121036; x=1786725836; darn=vger.kernel.org; h=content-type:cc:to:from:subject:message-id:references:mime-version :in-reply-to:date:from:to:cc:subject:date:message-id:reply-to :content-type; bh=kTVefapbptpCkdGjL+1kDLjlNC/ag2PzDpk3DPL7XNw=; b=pn214yGDFp4jn4WNxJ5LNAsL3508yQdHmJetiUmnqFaHqkoyQt+KggVjvRTUlTdU/V up2L96dNuvp7OH0H2jOZD+kOHY4Su0Crd+CRMhgfdU13zGZEhgwaOFSwRkCGdIbwmWjy Hm6KByn1V2TLpMMHRHoPpDftferCiCNXIMl6FhD/6HcCpLqX4pLq6CLmehA9btJeTlfi 6M5+W3PvmcQ0SEb8NBL+biu6T5ljdXLdv/5woC6nJOSLeN9Lo7oCcXmsQhcRx60MeZD7 ld6EcrN6KU27yn9IFxvqlziwvoow8PE4fEdO9nMTtiG3BEpchXAkP56nY+ogbp87/tZG NtpQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786121036; x=1786725836; h=content-type:cc:to:from:subject:message-id:references:mime-version :in-reply-to:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to:content-type; bh=kTVefapbptpCkdGjL+1kDLjlNC/ag2PzDpk3DPL7XNw=; b=nWajvnbearUyxmQDO2BgxcHtdlrF/3XB5MC0j2M4jGMwlcuryypIVhsUd3zP5/HzNz SkqmAcqqMfj+N+lp6+ZiO3yZl+e2tzletEeJR2A0BGvTjgvEqSsO/kb8bPPYmbuT7BLQ KoL6R0esEGffkQ5dPtO9zCLCeaufaP6z0F/QauYLX2iU4P58mY0nWpssbQaOSAhZqGxI UpOo5LeYGP97tGc//VZCUm1M02pcbWcJ6gIfqM2IuAAjlAA7VfauqgsLStO3hpmFVMiM Cnf++KiLfph+48BIvdE1B4U/jBI060OIo4SrkZv9m8bDK+kx3A/LJo96wPSEEWDJFyPc 4LkA== X-Forwarded-Encrypted: i=1; AHgh+RoXA1xnnGgUPulZlGZlJfSZDpmAWcDlZnyeRlylKW3VHZLTK77ny+WIRrAlI96tEo9IQHC3ja6Wm/1FHFQ=@vger.kernel.org X-Gm-Message-State: AOJu0YyxFVkYuDzHuY+9M3Tt6T4K5pE/3m/25RoNv9NuDLacIk7/JTRQ h/YUmSVt15CRUEKzvFFmMUDq5EaCN3g3LyGPXKA3BQTmFGGRHiU40z94t5vKunEprJQbXOI+xJ4 S9pJP7w6uSzhSw9bhBtIUDSHg5GNsww== X-Received: from ejoz15.prod.google.com ([2002:a17:906:668f:b0:c12:533f:6b88]) (user=sebastianene job=prod-delivery.src-stubby-dispatcher) by 2002:a17:906:2ad4:b0:c20:61e0:e3ab with SMTP id a640c23a62f3a-c2061e10ffbmr524125066b.3.1786121036039; Fri, 07 Aug 2026 09:43:56 -0700 (PDT) Date: Fri, 7 Aug 2026 16:43:22 +0000 In-Reply-To: <20260807164322.2970811-2-sebastianene@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260807164322.2970811-2-sebastianene@google.com> X-Mailer: git-send-email 2.55.0.654.g21b8a5bc05-goog Message-ID: <20260807164322.2970811-14-sebastianene@google.com> Subject: [PATCH v2 12/13] KVM: arm64: Prevent the host from programming new GITS_BASER tables From: Sebastian Ene To: catalin.marinas@arm.com, fuad.tabba@linux.dev, joey.gouly@arm.com, mark.rutland@arm.com, maz@kernel.org, oupton@kernel.org, rananta@google.com, Sascha.Bischoff@arm.com, suzuki.poulose@arm.com, will@kernel.org Cc: kvmarm@lists.linux.dev, android-kvm@google.com, bgrzesik@google.com, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, nathan@kernel.org, perlarsen@google.com, sebastianene@google.com, seiden@linux.ibm.com, smostafa@google.com, tglx@kernel.org, vdonnefort@google.com, vladimir.murzin@arm.com, yuzenghui@huawei.com, zenghui.yu@linux.dev Content-Type: text/plain; charset="UTF-8" Don't allow the host to change the layout of the tables or to modify the address programmed in the GITS_BASER registers to point to new tables and bypass the sanitization. Prevent the host from updating the ITS tables while the ITS is enabled and the tables are set to prevent undefined behavior. Signed-off-by: Sebastian Ene --- arch/arm64/kvm/hyp/nvhe/its_emulate.c | 44 +++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/arch/arm64/kvm/hyp/nvhe/its_emulate.c b/arch/arm64/kvm/hyp/nvhe/its_emulate.c index 97cfa31d90d1..82dc60dcde68 100644 --- a/arch/arm64/kvm/hyp/nvhe/its_emulate.c +++ b/arch/arm64/kvm/hyp/nvhe/its_emulate.c @@ -42,18 +42,23 @@ void its_emulate_forward_req(struct pkvm_protected_reg *region, u64 offset, bool struct its_handler { u64 offset; u8 access_size; + u8 num_registers; void (*write)(struct pkvm_protected_reg *region, u64 offset, u64 value); void (*read)(struct pkvm_protected_reg *region, u64 offset, u64 *read); }; -#define ITS_HANDLER(off, sz, write_cb, read_cb) \ +#define ITS_HANDLER_REG_PAIR(off, sz, registers, write_cb, read_cb) \ { \ .offset = (off), \ .access_size = (sz), \ + .num_registers = (registers), \ .write = (write_cb), \ .read = (read_cb), \ } +#define ITS_HANDLER(off, sz, write_cb, read_cb) \ + ITS_HANDLER_REG_PAIR(off, sz, 1, write_cb, read_cb) + struct dte_entry { u32 device_id; u64 itt_pfn; @@ -460,10 +465,42 @@ static void cbaser_read(struct pkvm_protected_reg *region, u64 offset, u64 *read *read = readq_relaxed(its->base + GITS_CBASER); } +static void baser_write(struct pkvm_protected_reg *region, u64 offset, u64 value) +{ + struct its_priv_state *its = region->priv; + u32 ctlr = readl_relaxed(its->base + GITS_CTLR); + int baser_idx; + u64 baser; + + if ((ctlr & GITS_CTLR_ENABLE) || !(ctlr & GITS_CTLR_QUIESCENT)) + return; + + baser_idx = (offset - GITS_BASER) >> 3; + baser = its->host_state->tables[baser_idx].val; + + /* Prevent if it tries to change from direct layout to indirect layout */ + if ((value & GITS_BASER_INDIRECT) != (baser & GITS_BASER_INDIRECT)) + return; + + /* Don't allow the host to point to new tables or new attributes */ + value &= ~(GENMASK_ULL(47, 12) | GENMASK_ULL(9, 0)); + value |= (baser & GENMASK_ULL(47, 12)) | (baser & GENMASK_ULL(9, 0)); + + writeq_relaxed(value, its->base + offset); +} + +static void baser_read(struct pkvm_protected_reg *region, u64 offset, u64 *read) +{ + struct its_priv_state *its = region->priv; + *read = readq_relaxed(its->base + offset); +} + static struct its_handler its_handlers[] = { ITS_HANDLER(GITS_CWRITER, sizeof(u64), cwriter_write, cwriter_read), ITS_HANDLER(GITS_CTLR, sizeof(u32), ctlr_write, ctlr_read), ITS_HANDLER(GITS_CBASER, sizeof(u64), cbaser_write, cbaser_read), + + ITS_HANDLER_REG_PAIR(GITS_BASER, sizeof(u64), 8, baser_write, baser_read), {}, }; @@ -472,13 +509,14 @@ void pkvm_its_emulate_handler(struct pkvm_protected_reg *region, u64 offset, boo { struct its_priv_state *priv = region->priv; struct its_handler *reg_handler; + u64 end; if (!priv || !IS_ALIGNED(offset, reg_size)) return; for (reg_handler = its_handlers; reg_handler->access_size; reg_handler++) { - if (reg_handler->offset > offset || - reg_handler->offset + reg_handler->access_size <= offset) + end = reg_handler->offset + reg_handler->access_size * reg_handler->num_registers; + if (reg_handler->offset > offset || end <= offset) continue; if (reg_handler->access_size < reg_size) -- 2.55.0.654.g21b8a5bc05-goog