Re: [PATCH v2 07/13] KVM: arm64: Restrict host access to the private ITS tables
From: Fuad Tabba
Date: Tue Sep 15 2026 - 11:54:14 EST
Hi Seb,
The approach is right, and it has the same gap as the command queue in
06. A few things:
On Fri, Aug 07, 2026 at 04:43:17PM +0000, Sebastian Ene wrote:
[...]
> Make the original layer innaccessible to the host by donating the table memory from the host to
nit: "innaccessible"
[...]
> +static int pkvm_host_unmap_last_level(void *shadow, size_t num_pages, u32 psz)
[...]
> + table_addr = table[i] & PHYS_MASK;
> + ret = __pkvm_host_donate_hyp(hyp_phys_to_pfn(table_addr), psz >> PAGE_SHIFT);
DIV_ROUND_UP(psz, PAGE_SIZE) would be safer here. psz >> PAGE_SHIFT is
zero when the ITS page size is below PAGE_SIZE, which
its_probe_baser_psz() can pick (a 4K-only ITS on a 16K or 64K kernel),
and then the L2 page is donated as zero pages and stays
host-accessible. Same in pkvm_host_map_last_level(). (Sashiko)
> +static int pkvm_share_shadow_table(void *shadow, u64 nr_pages)
> +{
> + u64 i, ret, start_pfn = hyp_virt_to_pfn(shadow);
ret could be an int; it holds the errno from __pkvm_host_share_hyp()
and the function returns int.
> +static int pkvm_setup_its_shadow_baser(struct its_host_state *host_state)
> +{
[...]
> + original_table = kern_hyp_va(host_state->tables[i].base);
> + num_pages = (1 << host_state->tables[i].order);
> +
> + ret = __pkvm_host_donate_hyp(hyp_virt_to_pfn(original_table), num_pages);
Could setup read GITS_BASER<n> and validate base and size against it?
base, order and the INDIRECT bit all come from the donated snapshot,
not the hardware, so as with the queue in 06 a compromised host
calling this hypercall can name a decoy table it owns: hyp protects
that one while the real table GITS_BASER<n> points at stays
host-writable, and the L1-pointer patching this restriction exists to
stop works on it. (Sashiko)
Cheers,
/fuad