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

[Xen-devel] [PATCH] x86: adjust PV I/O emulation functions' types



admin_io_okay(), guest_io_read(), and guest_io_write() all don't need
their current "regs" parameter at all, and they don't use the vCPU
passed to them for other than obtaining its domain. Drop the former and
replace the latter by a struct domain pointer.

pci_cfg_okay() returns a boolean type, and its "write" parameter is of
boolean kind too.

All of them get called for the current vCPU (and hence current domain)
only, so name the domain parameters accordingly except in the
admin_io_okay() case, which a subsequent patch will use for simplifying
setup_io_bitmap().

Latch current->domain into a local variable in emulate_privileged_op().

Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>

--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -599,13 +599,12 @@ static int hvm_access_cf8(
 static int handle_pvh_io(
     int dir, uint32_t port, uint32_t bytes, uint32_t *val)
 {
-    struct vcpu *curr = current;
-    struct cpu_user_regs *regs = guest_cpu_user_regs();
+    struct domain *currd = current->domain;
 
     if ( dir == IOREQ_WRITE )
-        guest_io_write(port, bytes, *val, curr, regs);
+        guest_io_write(port, bytes, *val, currd);
     else
-        *val = guest_io_read(port, bytes, curr, regs);
+        *val = guest_io_read(port, bytes, currd);
 
     return X86EMUL_OKAY;
 }
--- a/xen/arch/x86/traps.c
+++ b/xen/arch/x86/traps.c
@@ -1754,9 +1754,8 @@ static int guest_io_okay(
 }
 
 /* Has the administrator granted sufficient permission for this I/O access? */
-static int admin_io_okay(
-    unsigned int port, unsigned int bytes,
-    struct vcpu *v, struct cpu_user_regs *regs)
+static bool_t admin_io_okay(unsigned int port, unsigned int bytes,
+                            const struct domain *d)
 {
     /*
      * Port 0xcf8 (CONFIG_ADDRESS) is only visible for DWORD accesses.
@@ -1769,17 +1768,18 @@ static int admin_io_okay(
     if ( ((port & ~1) == RTC_PORT(0)) )
         return 0;
 
-    return ioports_access_permitted(v->domain, port, port + bytes - 1);
+    return ioports_access_permitted(d, port, port + bytes - 1);
 }
 
-static int pci_cfg_ok(struct domain *d, int write, int size)
+static bool_t pci_cfg_ok(struct domain *currd, bool_t write, unsigned int size)
 {
     uint32_t machine_bdf;
-    uint16_t start, end;
-    if (!is_hardware_domain(d))
+    unsigned int start;
+
+    if ( !is_hardware_domain(currd) )
         return 0;
 
-    machine_bdf = (d->arch.pci_cf8 >> 8) & 0xFFFF;
+    machine_bdf = (currd->arch.pci_cf8 >> 8) & 0xFFFF;
     if ( write )
     {
         const unsigned long *ro_map = pci_get_ro_map(0);
@@ -1787,9 +1787,9 @@ static int pci_cfg_ok(struct domain *d, 
         if ( ro_map && test_bit(machine_bdf, ro_map) )
             return 0;
     }
-    start = d->arch.pci_cf8 & 0xFF;
+    start = currd->arch.pci_cf8 & 0xFF;
     /* AMD extended configuration space access? */
-    if ( (d->arch.pci_cf8 & 0x0F000000) &&
+    if ( (currd->arch.pci_cf8 & 0x0F000000) &&
          boot_cpu_data.x86_vendor == X86_VENDOR_AMD &&
          boot_cpu_data.x86 >= 0x10 && boot_cpu_data.x86 <= 0x17 )
     {
@@ -1798,22 +1798,20 @@ static int pci_cfg_ok(struct domain *d, 
         if ( rdmsr_safe(MSR_AMD64_NB_CFG, msr_val) )
             return 0;
         if ( msr_val & (1ULL << AMD64_NB_CFG_CF8_EXT_ENABLE_BIT) )
-            start |= (d->arch.pci_cf8 >> 16) & 0xF00;
+            start |= (currd->arch.pci_cf8 >> 16) & 0xF00;
     }
-    end = start + size - 1;
-    if (xsm_pci_config_permission(XSM_HOOK, d, machine_bdf, start, end, write))
-        return 0;
-    return 1;
+
+    return !xsm_pci_config_permission(XSM_HOOK, currd, machine_bdf,
+                                      start, start + size - 1, write);
 }
 
-uint32_t guest_io_read(
-    unsigned int port, unsigned int bytes,
-    struct vcpu *v, struct cpu_user_regs *regs)
+uint32_t guest_io_read(unsigned int port, unsigned int bytes,
+                       struct domain *currd)
 {
     uint32_t data = 0;
     unsigned int shift = 0;
 
-    if ( admin_io_okay(port, bytes, v, regs) )
+    if ( admin_io_okay(port, bytes, currd) )
     {
         switch ( bytes )
         {
@@ -1834,31 +1832,30 @@ uint32_t guest_io_read(
         }
         else if ( (port == RTC_PORT(0)) )
         {
-            sub_data = v->domain->arch.cmos_idx;
+            sub_data = currd->arch.cmos_idx;
         }
         else if ( (port == RTC_PORT(1)) &&
-                  ioports_access_permitted(v->domain, RTC_PORT(0),
-                                           RTC_PORT(1)) )
+                  ioports_access_permitted(currd, RTC_PORT(0), RTC_PORT(1)) )
         {
             unsigned long flags;
 
             spin_lock_irqsave(&rtc_lock, flags);
-            outb(v->domain->arch.cmos_idx & 0x7f, RTC_PORT(0));
+            outb(currd->arch.cmos_idx & 0x7f, RTC_PORT(0));
             sub_data = inb(RTC_PORT(1));
             spin_unlock_irqrestore(&rtc_lock, flags);
         }
         else if ( (port == 0xcf8) && (bytes == 4) )
         {
             size = 4;
-            sub_data = v->domain->arch.pci_cf8;
+            sub_data = currd->arch.pci_cf8;
         }
         else if ( (port & 0xfffc) == 0xcfc )
         {
             size = min(bytes, 4 - (port & 3));
             if ( size == 3 )
                 size = 2;
-            if ( pci_cfg_ok(v->domain, 0, size) )
-                sub_data = pci_conf_read(v->domain->arch.pci_cf8, port & 3, 
size);
+            if ( pci_cfg_ok(currd, 0, size) )
+                sub_data = pci_conf_read(currd->arch.pci_cf8, port & 3, size);
         }
 
         if ( size == 4 )
@@ -1873,11 +1870,10 @@ uint32_t guest_io_read(
     return data;
 }
 
-void guest_io_write(
-    unsigned int port, unsigned int bytes, uint32_t data,
-    struct vcpu *v, struct cpu_user_regs *regs)
+void guest_io_write(unsigned int port, unsigned int bytes, uint32_t data,
+                    struct domain *currd)
 {
-    if ( admin_io_okay(port, bytes, v, regs) )
+    if ( admin_io_okay(port, bytes, currd) )
     {
         switch ( bytes ) {
         case 1:
@@ -1905,33 +1901,32 @@ void guest_io_write(
         }
         else if ( (port == RTC_PORT(0)) )
         {
-            v->domain->arch.cmos_idx = data;
+            currd->arch.cmos_idx = data;
         }
         else if ( (port == RTC_PORT(1)) &&
-                  ioports_access_permitted(v->domain, RTC_PORT(0),
-                                           RTC_PORT(1)) )
+                  ioports_access_permitted(currd, RTC_PORT(0), RTC_PORT(1)) )
         {
             unsigned long flags;
 
             if ( pv_rtc_handler )
-                pv_rtc_handler(v->domain->arch.cmos_idx & 0x7f, data);
+                pv_rtc_handler(currd->arch.cmos_idx & 0x7f, data);
             spin_lock_irqsave(&rtc_lock, flags);
-            outb(v->domain->arch.cmos_idx & 0x7f, RTC_PORT(0));
+            outb(currd->arch.cmos_idx & 0x7f, RTC_PORT(0));
             outb(data, RTC_PORT(1));
             spin_unlock_irqrestore(&rtc_lock, flags);
         }
         else if ( (port == 0xcf8) && (bytes == 4) )
         {
             size = 4;
-            v->domain->arch.pci_cf8 = data;
+            currd->arch.pci_cf8 = data;
         }
         else if ( (port & 0xfffc) == 0xcfc )
         {
             size = min(bytes, 4 - (port & 3));
             if ( size == 3 )
                 size = 2;
-            if ( pci_cfg_ok(v->domain, 1, size) )
-                pci_conf_write(v->domain->arch.pci_cf8, port & 3, size, data);
+            if ( pci_cfg_ok(currd, 1, size) )
+                pci_conf_write(currd->arch.pci_cf8, port & 3, size, data);
         }
 
         if ( size == 4 )
@@ -1989,6 +1984,7 @@ static int is_cpufreq_controller(struct 
 static int emulate_privileged_op(struct cpu_user_regs *regs)
 {
     struct vcpu *v = current;
+    struct domain *currd = v->domain;
     unsigned long *reg, eip = regs->eip;
     u8 opcode, modrm_reg = 0, modrm_rm = 0, rep_prefix = 0, lock = 0, rex = 0;
     enum { lm_seg_none, lm_seg_fs, lm_seg_gs } lm_ovr = lm_seg_none;
@@ -2145,7 +2141,7 @@ static int emulate_privileged_op(struct 
                  (rd_ad(edi) > (data_limit - (op_bytes - 1))) ||
                  !guest_io_okay(port, op_bytes, v, regs) )
                 goto fail;
-            data = guest_io_read(port, op_bytes, v, regs);
+            data = guest_io_read(port, op_bytes, currd);
             if ( (rc = copy_to_user((void *)data_base + rd_ad(edi),
                                     &data, op_bytes)) != 0 )
             {
@@ -2171,7 +2167,7 @@ static int emulate_privileged_op(struct 
                                      + op_bytes - rc, 0);
                 return EXCRET_fault_fixed;
             }
-            guest_io_write(port, op_bytes, data, v, regs);
+            guest_io_write(port, op_bytes, data, currd);
             wr_ad(esi, regs->esi + (int)((regs->eflags & X86_EFLAGS_DF)
                                          ? -op_bytes : op_bytes));
             break;
@@ -2232,7 +2228,7 @@ static int emulate_privileged_op(struct 
     exec_in:
         if ( !guest_io_okay(port, op_bytes, v, regs) )
             goto fail;
-        if ( admin_io_okay(port, op_bytes, v, regs) )
+        if ( admin_io_okay(port, op_bytes, currd) )
         {
             mark_regs_dirty(regs);
             io_emul(regs);            
@@ -2243,7 +2239,7 @@ static int emulate_privileged_op(struct 
                 regs->eax = 0;
             else
                 regs->eax &= ~((1 << (op_bytes * 8)) - 1);
-            regs->eax |= guest_io_read(port, op_bytes, v, regs);
+            regs->eax |= guest_io_read(port, op_bytes, currd);
         }
         bpmatch = check_guest_io_breakpoint(v, port, op_bytes);
         goto done;
@@ -2262,7 +2258,7 @@ static int emulate_privileged_op(struct 
     exec_out:
         if ( !guest_io_okay(port, op_bytes, v, regs) )
             goto fail;
-        if ( admin_io_okay(port, op_bytes, v, regs) )
+        if ( admin_io_okay(port, op_bytes, currd) )
         {
             mark_regs_dirty(regs);
             io_emul(regs);            
@@ -2271,7 +2267,7 @@ static int emulate_privileged_op(struct 
         }
         else
         {
-            guest_io_write(port, op_bytes, regs->eax, v, regs);
+            guest_io_write(port, op_bytes, regs->eax, currd);
         }
         bpmatch = check_guest_io_breakpoint(v, port, op_bytes);
         goto done;
@@ -2353,7 +2349,7 @@ static int emulate_privileged_op(struct 
 
     case 0x09: /* WBINVD */
         /* Ignore the instruction if unprivileged. */
-        if ( !cache_flush_permitted(v->domain) )
+        if ( !cache_flush_permitted(currd) )
             /* Non-physdev domain attempted WBINVD; ignore for now since
                newer linux uses this in some start-of-day timing loops */
             ;
@@ -2386,8 +2382,7 @@ static int emulate_privileged_op(struct 
             if ( !is_pv_32on64_vcpu(v) )
             {
                 mfn = pagetable_get_pfn(v->arch.guest_table);
-                *reg = xen_pfn_to_cr3(mfn_to_gmfn(
-                    v->domain, mfn));
+                *reg = xen_pfn_to_cr3(mfn_to_gmfn(currd, mfn));
             }
             else
             {
@@ -2396,8 +2391,7 @@ static int emulate_privileged_op(struct 
 
                 mfn = l4e_get_pfn(*pl4e);
                 unmap_domain_page(pl4e);
-                *reg = compat_pfn_to_cr3(mfn_to_gmfn(
-                    v->domain, mfn));
+                *reg = compat_pfn_to_cr3(mfn_to_gmfn(currd, mfn));
             }
             /* PTs should not be shared */
             BUG_ON(page_get_owner(mfn_to_page(mfn)) == dom_cow);
@@ -2457,7 +2451,7 @@ static int emulate_privileged_op(struct 
 
             gfn = !is_pv_32on64_vcpu(v)
                 ? xen_cr3_to_pfn(*reg) : compat_cr3_to_pfn(*reg);
-            page = get_page_from_gfn(v->domain, gfn, NULL, P2M_ALLOC);
+            page = get_page_from_gfn(currd, gfn, NULL, P2M_ALLOC);
             if ( page )
             {
                 rc = new_guest_cr3(page_to_mfn(page));
@@ -2541,7 +2535,7 @@ static int emulate_privileged_op(struct 
         case MSR_K8_HWCR:
             if ( boot_cpu_data.x86_vendor != X86_VENDOR_AMD )
                 goto fail;
-            if ( !is_cpufreq_controller(v->domain) )
+            if ( !is_cpufreq_controller(currd) )
                 break;
             if ( wrmsr_safe(regs->ecx, msr_content) != 0 )
                 goto fail;
@@ -2550,7 +2544,7 @@ static int emulate_privileged_op(struct 
             if ( boot_cpu_data.x86_vendor != X86_VENDOR_AMD ||
                  boot_cpu_data.x86 < 0x10 || boot_cpu_data.x86 > 0x17 )
                 goto fail;
-            if ( !is_hardware_domain(v->domain) || !is_pinned_vcpu(v) )
+            if ( !is_hardware_domain(currd) || !is_pinned_vcpu(v) )
                 break;
             if ( (rdmsr_safe(MSR_AMD64_NB_CFG, val) != 0) ||
                  (eax != (uint32_t)val) ||
@@ -2563,7 +2557,7 @@ static int emulate_privileged_op(struct 
             if ( boot_cpu_data.x86_vendor != X86_VENDOR_AMD ||
                  boot_cpu_data.x86 < 0x10 || boot_cpu_data.x86 > 0x17 )
                 goto fail;
-            if ( !is_hardware_domain(v->domain) || !is_pinned_vcpu(v) )
+            if ( !is_hardware_domain(currd) || !is_pinned_vcpu(v) )
                 break;
             if ( (rdmsr_safe(MSR_FAM10H_MMIO_CONF_BASE, val) != 0) )
                 goto fail;
@@ -2583,7 +2577,7 @@ static int emulate_privileged_op(struct 
         case MSR_IA32_UCODE_REV:
             if ( boot_cpu_data.x86_vendor != X86_VENDOR_INTEL )
                 goto fail;
-            if ( !is_hardware_domain(v->domain) || !is_pinned_vcpu(v) )
+            if ( !is_hardware_domain(currd) || !is_pinned_vcpu(v) )
                 break;
             if ( rdmsr_safe(regs->ecx, val) )
                 goto fail;
@@ -2602,7 +2596,7 @@ static int emulate_privileged_op(struct 
             if (( boot_cpu_data.x86_vendor != X86_VENDOR_INTEL ) &&
                 ( boot_cpu_data.x86_vendor != X86_VENDOR_AMD ) )
                 goto fail;
-            if ( !is_cpufreq_controller(v->domain) )
+            if ( !is_cpufreq_controller(currd) )
                 break;
             if ( wrmsr_safe(regs->ecx, msr_content ) != 0 )
                 goto fail;
@@ -2610,7 +2604,7 @@ static int emulate_privileged_op(struct 
         case MSR_IA32_PERF_CTL:
             if ( boot_cpu_data.x86_vendor != X86_VENDOR_INTEL )
                 goto fail;
-            if ( !is_cpufreq_controller(v->domain) )
+            if ( !is_cpufreq_controller(currd) )
                 break;
             if ( wrmsr_safe(regs->ecx, msr_content) != 0 )
                 goto fail;
@@ -2619,7 +2613,7 @@ static int emulate_privileged_op(struct 
         case MSR_IA32_ENERGY_PERF_BIAS:
             if ( boot_cpu_data.x86_vendor != X86_VENDOR_INTEL )
                 goto fail;
-            if ( !is_hardware_domain(v->domain) || !is_pinned_vcpu(v) )
+            if ( !is_hardware_domain(currd) || !is_pinned_vcpu(v) )
                 break;
             if ( wrmsr_safe(regs->ecx, msr_content) != 0 )
                 goto fail;
@@ -2665,7 +2659,7 @@ static int emulate_privileged_op(struct 
         if ( (v->arch.pv_vcpu.ctrlreg[4] & X86_CR4_TSD) &&
              !guest_kernel_mode(v, regs) )
             goto fail;
-        if ( v->domain->arch.vtsc )
+        if ( currd->arch.vtsc )
             pv_soft_rdtsc(v, regs, 0);
         else
         {
@@ -2708,7 +2702,7 @@ static int emulate_privileged_op(struct 
         case MSR_K8_PSTATE7:
             if ( boot_cpu_data.x86_vendor != X86_VENDOR_AMD )
                 goto fail;
-            if ( !is_cpufreq_controller(v->domain) )
+            if ( !is_cpufreq_controller(currd) )
             {
                 regs->eax = regs->edx = 0;
                 break;
--- a/xen/include/asm-x86/traps.h
+++ b/xen/include/asm-x86/traps.h
@@ -48,8 +48,8 @@ extern int send_guest_trap(struct domain
                                unsigned int trap_nr);
 
 uint32_t guest_io_read(unsigned int port, unsigned int bytes,
-                       struct vcpu *, struct cpu_user_regs *);
+                       struct domain *);
 void guest_io_write(unsigned int port, unsigned int bytes, uint32_t data,
-                    struct vcpu *, struct cpu_user_regs *);
+                    struct domain *);
 
 #endif /* ASM_TRAP_H */


Attachment: x86-guest-io-params.patch
Description: Text document

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel

 


Rackspace

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