[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen staging] x86: make traps.c build with !CONFIG_PV



commit aa0816b74f1dffe2d9f3e159915f9a399379278a
Author:     Wei Liu <wei.liu2@xxxxxxxxxx>
AuthorDate: Fri Nov 2 15:55:39 2018 +0000
Commit:     Wei Liu <wei.liu2@xxxxxxxxxx>
CommitDate: Mon Nov 5 16:08:03 2018 +0000

    x86: make traps.c build with !CONFIG_PV
    
    Provide a stub for pv_inject_event. Put code that accesses PV fields
    and GDT / LDT fault handling code under CONFIG_PV. Move set_debugreg
    to pv/misc-hypercalls.c.
    
    Signed-off-by: Wei Liu <wei.liu2@xxxxxxxxxx>
    Reviewed-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
---
 xen/arch/x86/pv/misc-hypercalls.c | 116 ++++++++++++++++++++++++++++++++++
 xen/arch/x86/traps.c              | 130 ++++----------------------------------
 xen/include/asm-x86/domain.h      |   7 ++
 3 files changed, 137 insertions(+), 116 deletions(-)

diff --git a/xen/arch/x86/pv/misc-hypercalls.c 
b/xen/arch/x86/pv/misc-hypercalls.c
index 9f61f3db3c..136fa10c96 100644
--- a/xen/arch/x86/pv/misc-hypercalls.c
+++ b/xen/arch/x86/pv/misc-hypercalls.c
@@ -56,6 +56,122 @@ long do_fpu_taskswitch(int set)
 }
 
 /*
+ * Used by hypercalls and the emulator.
+ *  -ENODEV => #UD
+ *  -EINVAL => #GP Invalid bit
+ *  -EPERM  => #GP Valid bit, but not permitted to use
+ */
+long set_debugreg(struct vcpu *v, unsigned int reg, unsigned long value)
+{
+    struct vcpu *curr = current;
+
+    switch ( reg )
+    {
+    case 0 ... 3:
+        if ( !access_ok(value, sizeof(long)) )
+            return -EPERM;
+
+        v->arch.dr[reg] = value;
+        if ( v == curr )
+        {
+            switch ( reg )
+            {
+            case 0: write_debugreg(0, value); break;
+            case 1: write_debugreg(1, value); break;
+            case 2: write_debugreg(2, value); break;
+            case 3: write_debugreg(3, value); break;
+            }
+        }
+        break;
+
+    case 4:
+        if ( v->arch.pv.ctrlreg[4] & X86_CR4_DE )
+            return -ENODEV;
+
+        /* Fallthrough */
+    case 6:
+        /* The upper 32 bits are strictly reserved. */
+        if ( value != (uint32_t)value )
+            return -EINVAL;
+
+        /*
+         * DR6: Bits 4-11,16-31 reserved (set to 1).
+         *      Bit 12 reserved (set to 0).
+         */
+        value &= ~DR_STATUS_RESERVED_ZERO; /* reserved bits => 0 */
+        value |=  DR_STATUS_RESERVED_ONE;  /* reserved bits => 1 */
+
+        v->arch.dr6 = value;
+        if ( v == curr )
+            write_debugreg(6, value);
+        break;
+
+    case 5:
+        if ( v->arch.pv.ctrlreg[4] & X86_CR4_DE )
+            return -ENODEV;
+
+        /* Fallthrough */
+    case 7:
+        /* The upper 32 bits are strictly reserved. */
+        if ( value != (uint32_t)value )
+            return -EINVAL;
+
+        /*
+         * DR7: Bit 10 reserved (set to 1).
+         *      Bits 11-12,14-15 reserved (set to 0).
+         */
+        value &= ~DR_CONTROL_RESERVED_ZERO; /* reserved bits => 0 */
+        value |=  DR_CONTROL_RESERVED_ONE;  /* reserved bits => 1 */
+        /*
+         * Privileged bits:
+         *      GD (bit 13): must be 0.
+         */
+        if ( value & DR_GENERAL_DETECT )
+            return -EPERM;
+
+        /* DR7.{G,L}E = 0 => debugging disabled for this domain. */
+        if ( value & DR7_ACTIVE_MASK )
+        {
+            unsigned int i, io_enable = 0;
+
+            for ( i = DR_CONTROL_SHIFT; i < 32; i += DR_CONTROL_SIZE )
+            {
+                if ( ((value >> i) & 3) == DR_IO )
+                {
+                    if ( !(v->arch.pv.ctrlreg[4] & X86_CR4_DE) )
+                        return -EPERM;
+                    io_enable |= value & (3 << ((i - 16) >> 1));
+                }
+            }
+
+            v->arch.pv.dr7_emul = io_enable;
+            value &= ~io_enable;
+
+            /*
+             * If DR7 was previously clear then we need to load all other
+             * debug registers at this point as they were not restored during
+             * context switch.  Updating DR7 itself happens later.
+             */
+            if ( (v == curr) && !(v->arch.dr7 & DR7_ACTIVE_MASK) )
+                activate_debugregs(v);
+        }
+        else
+            /* Zero the emulated controls if %dr7 isn't active. */
+            v->arch.pv.dr7_emul = 0;
+
+        v->arch.dr7 = value;
+        if ( v == curr )
+            write_debugreg(7, value);
+        break;
+
+    default:
+        return -ENODEV;
+    }
+
+    return 0;
+}
+
+/*
  * Local variables:
  * mode: C
  * c-file-style: "BSD"
diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c
index c60c8f5c2a..7765f9a5d7 100644
--- a/xen/arch/x86/traps.c
+++ b/xen/arch/x86/traps.c
@@ -1115,6 +1115,7 @@ static void reserved_bit_page_fault(unsigned long addr,
     show_execution_state(regs);
 }
 
+#ifdef CONFIG_PV
 static int handle_ldt_mapping_fault(unsigned int offset,
                                     struct cpu_user_regs *regs)
 {
@@ -1185,6 +1186,7 @@ static int handle_gdt_ldt_mapping_fault(unsigned long 
offset,
 
     return EXCRET_fault_fixed;
 }
+#endif
 
 #define IN_HYPERVISOR_RANGE(va) \
     (((va) >= HYPERVISOR_VIRT_START) && ((va) < HYPERVISOR_VIRT_END))
@@ -1335,10 +1337,12 @@ static int fixup_page_fault(unsigned long addr, struct 
cpu_user_regs *regs)
 
     if ( unlikely(IN_HYPERVISOR_RANGE(addr)) )
     {
+#ifdef CONFIG_PV
         if ( !(regs->error_code & (PFEC_user_mode | PFEC_reserved_bit)) &&
              (addr >= GDT_LDT_VIRT_START) && (addr < GDT_LDT_VIRT_END) )
             return handle_gdt_ldt_mapping_fault(
                 addr - GDT_LDT_VIRT_START, regs);
+#endif
         return 0;
     }
 
@@ -1494,7 +1498,9 @@ void __init do_early_page_fault(struct cpu_user_regs 
*regs)
 
 void do_general_protection(struct cpu_user_regs *regs)
 {
+#ifdef CONFIG_PV
     struct vcpu *v = current;
+#endif
     unsigned long fixup;
 
     if ( debugger_trap_entry(TRAP_gp_fault, regs) )
@@ -1506,6 +1512,7 @@ void do_general_protection(struct cpu_user_regs *regs)
     if ( !guest_mode(regs) )
         goto gp_in_kernel;
 
+#ifdef CONFIG_PV
     /*
      * Cunning trick to allow arbitrary "INT n" handling.
      *
@@ -1557,6 +1564,7 @@ void do_general_protection(struct cpu_user_regs *regs)
     /* Pass on GPF as is. */
     pv_inject_hw_exception(TRAP_gp_fault, regs->error_code);
     return;
+#endif
 
  gp_in_kernel:
 
@@ -1744,7 +1752,9 @@ void unset_nmi_callback(void)
 
 void do_device_not_available(struct cpu_user_regs *regs)
 {
+#ifdef CONFIG_PV
     struct vcpu *curr = current;
+#endif
 
     if ( !guest_mode(regs) )
     {
@@ -1762,6 +1772,7 @@ void do_device_not_available(struct cpu_user_regs *regs)
         return;
     }
 
+#ifdef CONFIG_PV
     vcpu_restore_fpu_lazy(curr);
 
     if ( curr->arch.pv.ctrlreg[0] & X86_CR0_TS )
@@ -1771,6 +1782,9 @@ void do_device_not_available(struct cpu_user_regs *regs)
     }
     else
         TRACE_0D(TRC_PV_MATH_STATE_RESTORE);
+#else
+    ASSERT_UNREACHABLE();
+#endif
 
     return;
 }
@@ -2078,122 +2092,6 @@ void activate_debugregs(const struct vcpu *curr)
     }
 }
 
-/*
- * Used by hypercalls and the emulator.
- *  -ENODEV => #UD
- *  -EINVAL => #GP Invalid bit
- *  -EPERM  => #GP Valid bit, but not permitted to use
- */
-long set_debugreg(struct vcpu *v, unsigned int reg, unsigned long value)
-{
-    struct vcpu *curr = current;
-
-    switch ( reg )
-    {
-    case 0 ... 3:
-        if ( !access_ok(value, sizeof(long)) )
-            return -EPERM;
-
-        v->arch.dr[reg] = value;
-        if ( v == curr )
-        {
-            switch ( reg )
-            {
-            case 0: write_debugreg(0, value); break;
-            case 1: write_debugreg(1, value); break;
-            case 2: write_debugreg(2, value); break;
-            case 3: write_debugreg(3, value); break;
-            }
-        }
-        break;
-
-    case 4:
-        if ( v->arch.pv.ctrlreg[4] & X86_CR4_DE )
-            return -ENODEV;
-
-        /* Fallthrough */
-    case 6:
-        /* The upper 32 bits are strictly reserved. */
-        if ( value != (uint32_t)value )
-            return -EINVAL;
-
-        /*
-         * DR6: Bits 4-11,16-31 reserved (set to 1).
-         *      Bit 12 reserved (set to 0).
-         */
-        value &= ~DR_STATUS_RESERVED_ZERO; /* reserved bits => 0 */
-        value |=  DR_STATUS_RESERVED_ONE;  /* reserved bits => 1 */
-
-        v->arch.dr6 = value;
-        if ( v == curr )
-            write_debugreg(6, value);
-        break;
-
-    case 5:
-        if ( v->arch.pv.ctrlreg[4] & X86_CR4_DE )
-            return -ENODEV;
-
-        /* Fallthrough */
-    case 7:
-        /* The upper 32 bits are strictly reserved. */
-        if ( value != (uint32_t)value )
-            return -EINVAL;
-
-        /*
-         * DR7: Bit 10 reserved (set to 1).
-         *      Bits 11-12,14-15 reserved (set to 0).
-         */
-        value &= ~DR_CONTROL_RESERVED_ZERO; /* reserved bits => 0 */
-        value |=  DR_CONTROL_RESERVED_ONE;  /* reserved bits => 1 */
-        /*
-         * Privileged bits:
-         *      GD (bit 13): must be 0.
-         */
-        if ( value & DR_GENERAL_DETECT )
-            return -EPERM;
-
-        /* DR7.{G,L}E = 0 => debugging disabled for this domain. */
-        if ( value & DR7_ACTIVE_MASK )
-        {
-            unsigned int i, io_enable = 0;
-
-            for ( i = DR_CONTROL_SHIFT; i < 32; i += DR_CONTROL_SIZE )
-            {
-                if ( ((value >> i) & 3) == DR_IO )
-                {
-                    if ( !(v->arch.pv.ctrlreg[4] & X86_CR4_DE) )
-                        return -EPERM;
-                    io_enable |= value & (3 << ((i - 16) >> 1));
-                }
-            }
-
-            v->arch.pv.dr7_emul = io_enable;
-            value &= ~io_enable;
-
-            /*
-             * If DR7 was previously clear then we need to load all other
-             * debug registers at this point as they were not restored during
-             * context switch.  Updating DR7 itself happens later.
-             */
-            if ( (v == curr) && !(v->arch.dr7 & DR7_ACTIVE_MASK) )
-                activate_debugregs(v);
-        }
-        else
-            /* Zero the emulated controls if %dr7 isn't active. */
-            v->arch.pv.dr7_emul = 0;
-
-        v->arch.dr7 = value;
-        if ( v == curr )
-            write_debugreg(7, value);
-        break;
-
-    default:
-        return -ENODEV;
-    }
-
-    return 0;
-}
-
 void asm_domain_crash_synchronous(unsigned long addr)
 {
     /*
diff --git a/xen/include/asm-x86/domain.h b/xen/include/asm-x86/domain.h
index 7214037820..643e69acf9 100644
--- a/xen/include/asm-x86/domain.h
+++ b/xen/include/asm-x86/domain.h
@@ -681,7 +681,14 @@ void arch_vcpu_regs_init(struct vcpu *v);
 struct vcpu_hvm_context;
 int arch_set_info_hvm_guest(struct vcpu *v, const struct vcpu_hvm_context 
*ctx);
 
+#ifdef CONFIG_PV
 void pv_inject_event(const struct x86_event *event);
+#else
+static inline void pv_inject_event(const struct x86_event *event)
+{
+    ASSERT_UNREACHABLE();
+}
+#endif
 
 static inline void pv_inject_hw_exception(unsigned int vector, int errcode)
 {
--
generated by git-patchbot for /home/xen/git/xen.git#staging

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/xen-changelog

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.