amd_iommu: Helper to decode size of page invalidation command

The size of the region to invalidate depends on the S bit and address
encoded in the command. Add a helper to extract this information, which
will be used to sync shadow page tables in upcoming changes.

Signed-off-by: Alejandro Jimenez <alejandro.j.jimenez@oracle.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20250919213515.917111-5-alejandro.j.jimenez@oracle.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
Alejandro Jimenez 2025-09-19 21:34:57 +00:00 committed by Michael S. Tsirkin
parent f76fc5d4ca
commit e8992fee66
2 changed files with 38 additions and 0 deletions

View file

@ -577,6 +577,40 @@ static gboolean amdvi_iotlb_remove_by_domid(gpointer key, gpointer value,
return entry->domid == domid;
}
/*
* Helper to decode the size of the range to invalidate encoded in the
* INVALIDATE_IOMMU_PAGES Command format.
* The size of the region to invalidate depends on the S bit and address.
* S bit value:
* 0 : Invalidation size is 4 Kbytes.
* 1 : Invalidation size is determined by first zero bit in the address
* starting from Address[12].
*
* In the AMD IOMMU Linux driver, an invalidation command with address
* ((1 << 63) - 1) is sent when intending to clear the entire cache.
* However, Table 14: Example Page Size Encodings shows that an address of
* ((1ULL << 51) - 1) encodes the entire cache, so effectively any address with
* first zero at bit 51 or larger is a request to invalidate the entire address
* space.
*/
static uint64_t __attribute__((unused))
amdvi_decode_invalidation_size(hwaddr addr, uint16_t flags)
{
uint64_t size = AMDVI_PAGE_SIZE;
uint8_t fzbit = 0;
if (flags & AMDVI_CMD_INVAL_IOMMU_PAGES_S) {
fzbit = cto64(addr | 0xFFF);
if (fzbit >= 51) {
size = AMDVI_INV_ALL_PAGES;
} else {
size = 1ULL << (fzbit + 1);
}
}
return size;
}
/* we don't have devid - we can't remove pages by address */
static void amdvi_inval_pages(AMDVIState *s, uint64_t *cmd)
{

View file

@ -126,6 +126,10 @@
#define AMDVI_CMD_COMPLETE_PPR_REQUEST 0x07
#define AMDVI_CMD_INVAL_AMDVI_ALL 0x08
#define AMDVI_CMD_INVAL_IOMMU_PAGES_S (1ULL << 0)
#define AMDVI_INV_ALL_PAGES (1ULL << 52)
#define AMDVI_DEVTAB_ENTRY_SIZE 32
/* Device table entry bits 0:63 */