p2m_access_t p2ma;
struct p2m_domain *p2m = NULL;
+ /*
+ * Since HW doesn't explicitly provide a read access bit and we need to
+ * somehow describe read-modify-write instructions we will conservatively
+ * set read_access for all memory accesses that are not instruction fetches.
+ */
struct npfec npfec = {
- .read_access = 1, /* All NPFs count as reads */
+ .read_access = !(pfec & PFEC_insn_fetch),
.write_access = !!(pfec & PFEC_write_access),
.insn_fetch = !!(pfec & PFEC_insn_fetch)
};
p2m_type_t p2mt;
int ret;
struct domain *d = current->domain;
+
+ /*
+ * We treat all write violations also as read violations.
+ * The reason why this is required is the following warning:
+ * "An EPT violation that occurs during as a result of execution of a
+ * read-modify-write operation sets bit 1 (data write). Whether it also
+ * sets bit 0 (data read) is implementation-specific and, for a given
+ * implementation, may differ for different kinds of read-modify-write
+ * operations."
+ * - Intel(R) 64 and IA-32 Architectures Software Developer's Manual
+ * Volume 3C: System Programming Guide, Part 3
+ */
struct npfec npfec = {
- .read_access = !!(qualification & EPT_READ_VIOLATION),
+ .read_access = !!(qualification & EPT_READ_VIOLATION) ||
+ !!(qualification & EPT_WRITE_VIOLATION),
.write_access = !!(qualification & EPT_WRITE_VIOLATION),
.insn_fetch = !!(qualification & EPT_EXEC_VIOLATION)
};