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;
*/
#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
*
("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", [
| CAP_DirectIO
| CAP_HAP
| CAP_Shadow
+ | CAP_IOMMU_HAP_PT_SHARE
type physinfo =
{
| CDF_OOS_OFF
| CDF_XS_DOMAIN
| CDF_IOMMU
-
type domctl_create_config = {
ssidref: int32;
handle: string;
| CAP_DirectIO
| CAP_HAP
| CAP_Shadow
+ | CAP_IOMMU_HAP_PT_SHARE
+
type physinfo = {
threads_per_core : int;
cores_per_socket : int;
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);
.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;
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");
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;
* 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 */
* 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;
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;
iommu_enabled = (rc == 0);
}
if ( !iommu_enabled )
+ {
iommu_intremap = 0;
+ clear_iommu_hap_pt_share();
+ }
if ( (force_iommu && !iommu_enabled) ||
(force_intremap && !iommu_intremap) )
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 )
/* 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;
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;