static const u32 msrpm_ranges[] = {0, 0xc0000000, 0xc0010000};
-#define NUM_MSR_MAPS ARRAY_SIZE(msrpm_ranges)
-#define MSRS_RANGE_SIZE 2048
-#define MSRS_IN_RANGE (MSRS_RANGE_SIZE * 8 / 2)
-
u32 svm_msrpm_offset(u32 msr)
{
u32 offset;
int i;
- for (i = 0; i < NUM_MSR_MAPS; i++) {
+ for (i = 0; i < ARRAY_SIZE(msrpm_ranges); i++) {
if (msr < msrpm_ranges[i] ||
- msr >= msrpm_ranges[i] + MSRS_IN_RANGE)
+ msr >= msrpm_ranges[i] + SVM_MSRS_PER_RANGE)
continue;
- offset = (msr - msrpm_ranges[i]) / 4; /* 4 msrs per u8 */
- offset += (i * MSRS_RANGE_SIZE); /* add range offset */
+ offset = (msr - msrpm_ranges[i]) / SVM_MSRS_PER_BYTE;
+ offset += (i * SVM_MSRPM_BYTES_PER_RANGE); /* add range offset */
/* Now we have the u8 offset - but need the u32 offset */
return offset / 4;
svm_vmgexit_set_return_code(svm, GHCB_HV_RESP_NO_ACTION, data);
}
-/* svm.c */
+/*
+ * The MSRPM is 8KiB in size, divided into four 2KiB ranges (the fourth range
+ * is reserved). Each MSR within a range is covered by two bits, one each for
+ * read (bit 0) and write (bit 1), where a bit value of '1' means intercepted.
+ */
+#define SVM_MSRPM_BYTES_PER_RANGE 2048
+#define SVM_BITS_PER_MSR 2
+#define SVM_MSRS_PER_BYTE (BITS_PER_BYTE / SVM_BITS_PER_MSR)
+#define SVM_MSRS_PER_RANGE (SVM_MSRPM_BYTES_PER_RANGE * SVM_MSRS_PER_BYTE)
+static_assert(SVM_MSRS_PER_RANGE == 8192);
+
#define MSR_INVALID 0xffffffffU
#define DEBUGCTL_RESERVED_BITS (~DEBUGCTLMSR_LBR)
+/* svm.c */
extern bool dump_invalid_vmcb;
u32 svm_msrpm_offset(u32 msr);