sysctl / libxl: report whether IOMMU/HAP page table sharing is supported

This patch defines a new bit reported in the hw_cap field of struct
xen_sysctl_physinfo to indicate whether the platform supports sharing of
HAP page tables (i.e. the P2M) with the IOMMU. This informs the toolstack
whether the domain needs extra memory to store discrete IOMMU page tables
or not.

NOTE: This patch makes sure iommu_hap_pt_shared is clear if HAP is not
      supported or the IOMMU is disabled, and defines it to false if
      !CONFIG_HVM.

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Christian Lindig <christian.lindig@citrix.com>
Acked-by: Wei Liu <wl@xen.org>
Acked-by: Julien Grall <julien.grall@arm.com>
This commit is contained in:
Paul Durrant authored and Jan Beulich committed 2019-09-17 16:12:47 +02:00
1 parent 71e617a6b8
commit c0902a9a14
13 files changed
+71 -15

No files matched your search

+2
View File
@@ -402,6 +402,8 @@ int libxl_get_physinfo(libxl_ctx *ctx, libxl_physinfo *physinfo)
physinfo->cap_hap = !!(xcphysinfo.capabilities & XEN_SYSCTL_PHYSCAP_hap);
physinfo->cap_shadow =
!!(xcphysinfo.capabilities & XEN_SYSCTL_PHYSCAP_shadow);
physinfo->cap_iommu_hap_pt_share =
!!(xcphysinfo.capabilities & XEN_SYSCTL_PHYSCAP_iommu_hap_pt_share);
GC_FREE;
return 0;
+7
View File
@@ -401,6 +401,13 @@
*/
#define LIBXL_HAVE_PHYSINFO_CAP_HAP_SHADOW 1
/*
* LIBXL_HAVE_PHYSINFO_CAP_IOMMU_HAP_PT_SHARE indicates that libxl_physinfo
* has a cap_iommu_hap_pt_share field that indicates whether the hardware
* supports sharing the IOMMU and HAP page tables.
*/
#define LIBXL_HAVE_PHYSINFO_CAP_IOMMU_HAP_PT_SHARE 1
/*
* libxl ABI compatibility
*
+1
View File
@@ -1027,6 +1027,7 @@ libxl_physinfo = Struct("physinfo", [
("cap_hvm_directio", bool), # No longer HVM specific
("cap_hap", bool),
("cap_shadow", bool),
("cap_iommu_hap_pt_share", bool),
], dir=DIR_OUT)
libxl_connectorinfo = Struct("connectorinfo", [
+1
View File
@@ -110,6 +110,7 @@ type physinfo_cap_flag =
| CAP_DirectIO
| CAP_HAP
| CAP_Shadow
| CAP_IOMMU_HAP_PT_SHARE
type physinfo =
{
+2 -1
View File
@@ -57,7 +57,6 @@ type domain_create_flag =
| CDF_OOS_OFF
| CDF_XS_DOMAIN
| CDF_IOMMU
type domctl_create_config = {
ssidref: int32;
handle: string;
@@ -95,6 +94,8 @@ type physinfo_cap_flag =
| CAP_DirectIO
| CAP_HAP
| CAP_Shadow
| CAP_IOMMU_HAP_PT_SHARE
type physinfo = {
threads_per_core : int;
cores_per_socket : int;
+3 -2
View File
@@ -210,13 +210,14 @@ static void output_physinfo(void)
info.hw_cap[4], info.hw_cap[5], info.hw_cap[6], info.hw_cap[7]
);
maybe_printf("virt_caps :%s%s%s%s%s%s\n",
maybe_printf("virt_caps :%s%s%s%s%s%s%s\n",
info.cap_pv ? " pv" : "",
info.cap_hvm ? " hvm" : "",
info.cap_hvm && info.cap_hvm_directio ? " hvm_directio" : "",
info.cap_pv && info.cap_hvm_directio ? " pv_directio" : "",
info.cap_hap ? " hap" : "",
info.cap_shadow ? " shadow" : ""
info.cap_shadow ? " shadow" : "",
info.cap_iommu_hap_pt_share ? " iommu_hap_pt_share" : ""
);
vinfo = libxl_get_version_info(ctx);
+19 -7
View File
@@ -142,6 +142,23 @@ static struct notifier_block cpu_nfb = {
.notifier_call = cpu_callback
};
static bool __init hap_supported(const struct hvm_function_table *fns)
{
if ( !fns->hap_supported )
{
printk("HVM: Hardware Assisted Paging (HAP) not detected\n");
return false;
}
if ( !opt_hap_enabled )
{
printk("HVM: Hardware Assisted Paging (HAP) detected but disabled\n");
return false;
}
return true;
}
static int __init hvm_enable(void)
{
const struct hvm_function_table *fns = NULL;
@@ -158,13 +175,8 @@ static int __init hvm_enable(void)
hvm_enabled = 1;
printk("HVM: %s enabled\n", fns->name);
if ( !fns->hap_supported )
printk("HVM: Hardware Assisted Paging (HAP) not detected\n");
else if ( !opt_hap_enabled )
{
hvm_funcs.hap_supported = 0;
printk("HVM: Hardware Assisted Paging (HAP) detected but disabled\n");
}
if ( !hap_supported(fns) )
clear_iommu_hap_pt_share();
else
{
printk("HVM: Hardware Assisted Paging (HAP) detected\n");
+2
View File
@@ -269,6 +269,8 @@ long do_sysctl(XEN_GUEST_HANDLE_PARAM(xen_sysctl_t) u_sysctl)
arch_do_physinfo(pi);
if ( iommu_enabled )
pi->capabilities |= XEN_SYSCTL_PHYSCAP_directio;
if ( iommu_hap_pt_share )
pi->capabilities |= XEN_SYSCTL_PHYSCAP_iommu_hap_pt_share;
if ( copy_to_guest(u_sysctl, op, 1) )
ret = -EFAULT;
+2 -1
View File
@@ -1412,7 +1412,8 @@ int __init amd_iommu_init(bool xt)
* since it only supports p2m_ram_rw, and this would
* prevent doing IO to/from mapped grant frames.
*/
iommu_hap_pt_share = 0;
clear_iommu_hap_pt_share();
printk(XENLOG_DEBUG "AMD-Vi: Disabled HAP memory map sharing with IOMMU\n");
/* per iommu initialization */
+10 -1
View File
@@ -49,7 +49,11 @@ int8_t __hwdom_initdata iommu_hwdom_reserved = -1;
* default until we find a good solution to resolve it.
*/
bool_t __read_mostly iommu_intpost;
bool_t __read_mostly iommu_hap_pt_share = 1;
#ifndef iommu_hap_pt_share
bool __read_mostly iommu_hap_pt_share = true;
#endif
bool_t __read_mostly iommu_debug;
bool_t __read_mostly amd_iommu_perdev_intremap = 1;
@@ -102,8 +106,10 @@ static int __init parse_iommu_param(const char *s)
iommu_hwdom_passthrough = val;
else if ( (val = parse_boolean("dom0-strict", s, ss)) >= 0 )
iommu_hwdom_strict = val;
#ifndef iommu_hap_pt_share
else if ( (val = parse_boolean("sharept", s, ss)) >= 0 )
iommu_hap_pt_share = val;
#endif
else
rc = -EINVAL;
@@ -511,7 +517,10 @@ int __init iommu_setup(void)
iommu_enabled = (rc == 0);
}
if ( !iommu_enabled )
{
iommu_intremap = 0;
clear_iommu_hap_pt_share();
}
if ( (force_iommu && !iommu_enabled) ||
(force_intremap && !iommu_intremap) )
+1 -1
View File
@@ -2310,7 +2310,7 @@ static int __init vtd_setup(void)
iommu_intpost = 0;
if ( !vtd_ept_page_compatible(iommu) )
iommu_hap_pt_share = 0;
clear_iommu_hap_pt_share();
ret = iommu_set_interrupt(drhd);
if ( ret )
+5 -1
View File
@@ -96,9 +96,13 @@ struct xen_sysctl_tbuf_op {
/* The platform supports software paging. */
#define _XEN_SYSCTL_PHYSCAP_shadow 4
#define XEN_SYSCTL_PHYSCAP_shadow (1u<<_XEN_SYSCTL_PHYSCAP_shadow)
/* The platform supports sharing of HAP page tables with the IOMMU. */
#define _XEN_SYSCTL_PHYSCAP_iommu_hap_pt_share 5
#define XEN_SYSCTL_PHYSCAP_iommu_hap_pt_share \
(1u << _XEN_SYSCTL_PHYSCAP_iommu_hap_pt_share)
/* Max XEN_SYSCTL_PHYSCAP_* constant. Used for ABI checking. */
#define XEN_SYSCTL_PHYSCAP_MAX XEN_SYSCTL_PHYSCAP_shadow
#define XEN_SYSCTL_PHYSCAP_MAX XEN_SYSCTL_PHYSCAP_iommu_hap_pt_share
struct xen_sysctl_physinfo {
uint32_t threads_per_core;
+16 -1
View File
@@ -55,7 +55,22 @@ static inline bool_t dfn_eq(dfn_t x, dfn_t y)
extern bool_t iommu_enable, iommu_enabled;
extern bool_t force_iommu, iommu_verbose, iommu_igfx;
extern bool_t iommu_snoop, iommu_qinval, iommu_intremap, iommu_intpost;
extern bool_t iommu_hap_pt_share;
#ifdef CONFIG_HVM
extern bool iommu_hap_pt_share;
#else
#define iommu_hap_pt_share false
#endif
static inline void clear_iommu_hap_pt_share(void)
{
#ifndef iommu_hap_pt_share
iommu_hap_pt_share = false;
#elif iommu_hap_pt_share
ASSERT_UNREACHABLE();
#endif
}
extern bool_t iommu_debug;
extern bool_t amd_iommu_perdev_intremap;
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.