#include <uapi/asm/svm.h>
 
+/*
+ * 32-bit intercept words in the VMCB Control Area, starting
+ * at Byte offset 000h.
+ */
+
+enum intercept_words {
+       MAX_INTERCEPT,
+};
 
 enum {
        INTERCEPT_INTR,
 
 
 struct __attribute__ ((__packed__)) vmcb_control_area {
+       u32 intercepts[MAX_INTERCEPT];
        u32 intercept_cr;
        u32 intercept_dr;
        u32 intercept_exceptions;
 
 void recalc_intercepts(struct vcpu_svm *svm)
 {
        struct vmcb_control_area *c, *h, *g;
+       unsigned int i;
 
        vmcb_mark_dirty(svm->vmcb, VMCB_INTERCEPTS);
 
        h = &svm->nested.hsave->control;
        g = &svm->nested.ctl;
 
+       for (i = 0; i < MAX_INTERCEPT; i++)
+               c->intercepts[i] = h->intercepts[i];
+
        c->intercept_cr = h->intercept_cr;
        c->intercept_dr = h->intercept_dr;
        c->intercept_exceptions = h->intercept_exceptions;
        /* We don't want to see VMMCALLs from a nested guest */
        c->intercept &= ~(1ULL << INTERCEPT_VMMCALL);
 
+       for (i = 0; i < MAX_INTERCEPT; i++)
+               c->intercepts[i] |= g->intercepts[i];
+
        c->intercept_cr |= g->intercept_cr;
        c->intercept_dr |= g->intercept_dr;
        c->intercept_exceptions |= g->intercept_exceptions;
 static void copy_vmcb_control_area(struct vmcb_control_area *dst,
                                   struct vmcb_control_area *from)
 {
+       unsigned int i;
+
+       for (i = 0; i < MAX_INTERCEPT; i++)
+               dst->intercepts[i] = from->intercepts[i];
+
        dst->intercept_cr         = from->intercept_cr;
        dst->intercept_dr         = from->intercept_dr;
        dst->intercept_exceptions = from->intercept_exceptions;
 
                return svm->vmcb;
 }
 
+static inline void vmcb_set_intercept(struct vmcb_control_area *control, u32 bit)
+{
+       WARN_ON_ONCE(bit >= 32 * MAX_INTERCEPT);
+       __set_bit(bit, (unsigned long *)&control->intercepts);
+}
+
+static inline void vmcb_clr_intercept(struct vmcb_control_area *control, u32 bit)
+{
+       WARN_ON_ONCE(bit >= 32 * MAX_INTERCEPT);
+       __clear_bit(bit, (unsigned long *)&control->intercepts);
+}
+
+static inline bool vmcb_is_intercept(struct vmcb_control_area *control, u32 bit)
+{
+       WARN_ON_ONCE(bit >= 32 * MAX_INTERCEPT);
+       return test_bit(bit, (unsigned long *)&control->intercepts);
+}
+
 static inline void set_cr_intercept(struct vcpu_svm *svm, int bit)
 {
        struct vmcb *vmcb = get_host_vmcb(svm);