x86/HVM: allocate emulation cache entries dynamically

Both caches may need higher capacity, and the upper bound will need to
be determined dynamically based on CPUID policy (for AMX'es TILELOAD /
TILESTORE at least).

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
Release-Acked-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
This commit is contained in:
Jan Beulich committed 2025-01-24 10:15:29 +01:00
1 parent e5339bb689
commit 23d60dbb04
3 files changed
+46 -25

No files matched your search

+39 -12
View File
@@ -26,6 +26,18 @@
#include <asm/iocap.h>
#include <asm/vm_event.h>
/*
* We may read or write up to m512 or up to a tile row as a number of
* device-model transactions.
*/
struct hvm_mmio_cache {
unsigned long gla;
unsigned int size; /* Amount of buffer[] actually used. */
unsigned int space:31; /* Allocated size of buffer[]. */
unsigned int dir:1;
uint8_t buffer[] __aligned(sizeof(long));
};
struct hvmemul_cache
{
/* The cache is disabled as long as num_ents > max_ents. */
@@ -935,7 +947,7 @@ static int hvmemul_phys_mmio_access(
}
/* Accesses must not overflow the cache's buffer. */
if ( offset + size > sizeof(cache->buffer) )
if ( offset + size > cache->space )
{
ASSERT_UNREACHABLE();
return X86EMUL_UNHANDLEABLE;
@@ -1011,7 +1023,7 @@ static struct hvm_mmio_cache *hvmemul_find_mmio_cache(
for ( i = 0; i < hvio->mmio_cache_count; i ++ )
{
cache = &hvio->mmio_cache[i];
cache = hvio->mmio_cache[i];
if ( gla == cache->gla &&
dir == cache->dir )
@@ -1027,10 +1039,11 @@ static struct hvm_mmio_cache *hvmemul_find_mmio_cache(
++hvio->mmio_cache_count;
cache = &hvio->mmio_cache[i];
memset(cache, 0, sizeof (*cache));
cache = hvio->mmio_cache[i];
memset(cache->buffer, 0, cache->space);
cache->gla = gla;
cache->size = 0;
cache->dir = dir;
return cache;
@@ -2980,16 +2993,21 @@ void hvm_dump_emulation_state(const char *loglvl, const char *prefix,
int hvmemul_cache_init(struct vcpu *v)
{
/*
* No insn can access more than 16 independent linear addresses (AVX512F
* scatters/gathers being the worst). Each such linear range can span a
* page boundary, i.e. may require two page walks. Account for each insn
* byte individually, for simplicity.
* AVX512F scatter/gather insns can access up to 16 independent linear
* addresses, up to 8 bytes size. Each such linear range can span a page
* boundary, i.e. may require two page walks.
*/
const unsigned int nents = (CONFIG_PAGING_LEVELS + 1) *
(MAX_INST_LEN + 16 * 2);
struct hvmemul_cache *cache = xmalloc_flex_struct(struct hvmemul_cache,
ents, nents);
unsigned int nents = 16 * 2 * (CONFIG_PAGING_LEVELS + 1);
unsigned int i, max_bytes = 64;
struct hvmemul_cache *cache;
/*
* Account for each insn byte individually, both for simplicity and to
* leave some slack space.
*/
nents += MAX_INST_LEN * (CONFIG_PAGING_LEVELS + 1);
cache = xvmalloc_flex_struct(struct hvmemul_cache, ents, nents);
if ( !cache )
return -ENOMEM;
@@ -2999,6 +3017,15 @@ int hvmemul_cache_init(struct vcpu *v)
v->arch.hvm.hvm_io.cache = cache;
for ( i = 0; i < ARRAY_SIZE(v->arch.hvm.hvm_io.mmio_cache); ++i )
{
v->arch.hvm.hvm_io.mmio_cache[i] =
xvmalloc_flex_struct(struct hvm_mmio_cache, buffer, max_bytes);
if ( !v->arch.hvm.hvm_io.mmio_cache[i] )
return -ENOMEM;
v->arch.hvm.hvm_io.mmio_cache[i]->space = max_bytes;
}
return 0;
}
+6 -1
View File
@@ -15,6 +15,7 @@
#include <xen/err.h>
#include <xen/mm.h>
#include <xen/sched.h>
#include <xen/xvmalloc.h>
#include <asm/hvm/hvm.h>
#include <asm/x86_emulate.h>
@@ -119,7 +120,11 @@ int hvmemul_do_pio_buffer(uint16_t port,
int __must_check hvmemul_cache_init(struct vcpu *v);
static inline void hvmemul_cache_destroy(struct vcpu *v)
{
XFREE(v->arch.hvm.hvm_io.cache);
unsigned int i;
for ( i = 0; i < ARRAY_SIZE(v->arch.hvm.hvm_io.mmio_cache); ++i )
XFREE(v->arch.hvm.hvm_io.mmio_cache[i]);
XVFREE(v->arch.hvm.hvm_io.cache);
}
bool hvmemul_read_cache(const struct vcpu *v, paddr_t gpa,
void *buffer, unsigned int size);
+1 -12
View File
@@ -22,17 +22,6 @@ struct hvm_vcpu_asid {
uint32_t asid;
};
/*
* We may read or write up to m512 as a number of device-model
* transactions.
*/
struct hvm_mmio_cache {
unsigned long gla;
unsigned int size;
uint8_t dir;
uint8_t buffer[64] __aligned(sizeof(long));
};
struct hvm_vcpu_io {
/*
* HVM emulation:
@@ -48,7 +37,7 @@ struct hvm_vcpu_io {
* We may need to handle up to 3 distinct memory accesses per
* instruction.
*/
struct hvm_mmio_cache mmio_cache[3];
struct hvm_mmio_cache *mmio_cache[3];
unsigned int mmio_cache_count;
/* For retries we shouldn't re-fetch the instruction. */
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.