Pull pvops into release branch
authorTony Luck <aegl@agluck-desktop.(none)>
Tue, 31 Mar 2009 21:25:08 +0000 (14:25 -0700)
committerTony Luck <tony.luck@intel.com>
Tue, 31 Mar 2009 21:25:08 +0000 (14:25 -0700)
1  2 
arch/ia64/include/asm/intrinsics.h
arch/ia64/kernel/Makefile
arch/ia64/kernel/setup.c
arch/ia64/kernel/vmlinux.lds.S
arch/ia64/kvm/kvm-ia64.c
arch/ia64/kvm/vcpu.c
arch/ia64/kvm/vtlb.c

index c47830e26cb7dd310af374b9b8ccd60194bef129,fbe2ad9234d058c508b4736f942dd34127c7e0e8..111ed52228921cac226a8994e404e3100defb73c
@@@ -10,7 -10,6 +10,7 @@@
  
  #ifndef __ASSEMBLY__
  
 +#include <linux/types.h>
  /* include compiler specific intrinsics */
  #include <asm/ia64regs.h>
  #ifdef __INTEL_COMPILER
@@@ -202,7 -201,11 +202,11 @@@ extern long ia64_cmpxchg_called_with_ba
  
  #ifndef __ASSEMBLY__
  #if defined(CONFIG_PARAVIRT) && defined(__KERNEL__)
- #define IA64_INTRINSIC_API(name)      pv_cpu_ops.name
+ #ifdef ASM_SUPPORTED
+ # define IA64_INTRINSIC_API(name)     paravirt_ ## name
+ #else
+ # define IA64_INTRINSIC_API(name)     pv_cpu_ops.name
+ #endif
  #define IA64_INTRINSIC_MACRO(name)    paravirt_ ## name
  #else
  #define IA64_INTRINSIC_API(name)      ia64_native_ ## name
index f2778f2c4fd9307f75c989fc8553364efe1b9253,dbc19e4d5ef7f32d176c9ce51b0dc0e19d517299..5628e9a990a61225196c5de205ebdceeaf800aee
@@@ -5,9 -5,9 +5,9 @@@
  extra-y       := head.o init_task.o vmlinux.lds
  
  obj-y := acpi.o entry.o efi.o efi_stub.o gate-data.o fsys.o ia64_ksyms.o irq.o irq_ia64.o     \
-        irq_lsapic.o ivt.o machvec.o pal.o patch.o process.o perfmon.o ptrace.o sal.o          \
+        irq_lsapic.o ivt.o machvec.o pal.o paravirt_patchlist.o patch.o process.o perfmon.o ptrace.o sal.o             \
         salinfo.o setup.o signal.o sys_ia64.o time.o traps.o unaligned.o \
 -       unwind.o mca.o mca_asm.o topology.o
 +       unwind.o mca.o mca_asm.o topology.o dma-mapping.o
  
  obj-$(CONFIG_IA64_BRL_EMU)    += brl_emu.o
  obj-$(CONFIG_IA64_GENERIC)    += acpi-ext.o
@@@ -36,44 -36,25 +36,23 @@@ obj-$(CONFIG_PCI_MSI)              += msi_ia64.
  mca_recovery-y                        += mca_drv.o mca_drv_asm.o
  obj-$(CONFIG_IA64_MC_ERR_INJECT)+= err_inject.o
  
- obj-$(CONFIG_PARAVIRT)                += paravirt.o paravirtentry.o
+ obj-$(CONFIG_PARAVIRT)                += paravirt.o paravirtentry.o \
+                                  paravirt_patch.o
  
  obj-$(CONFIG_IA64_ESI)                += esi.o
  ifneq ($(CONFIG_IA64_ESI),)
  obj-y                         += esi_stub.o   # must be in kernel proper
  endif
  obj-$(CONFIG_DMAR)            += pci-dma.o
 -ifeq ($(CONFIG_DMAR), y)
  obj-$(CONFIG_SWIOTLB)         += pci-swiotlb.o
 -endif
  
- # The gate DSO image is built using a special linker script.
- targets += gate.so gate-syms.o
- extra-y += gate.so gate-syms.o gate.lds gate.o
  # fp_emulate() expects f2-f5,f16-f31 to contain the user-level state.
  CFLAGS_traps.o  += -mfixed-range=f2-f5,f16-f31
  
- CPPFLAGS_gate.lds := -P -C -U$(ARCH)
- quiet_cmd_gate = GATE $@
-       cmd_gate = $(CC) -nostdlib $(GATECFLAGS_$(@F)) -Wl,-T,$(filter-out FORCE,$^) -o $@
- GATECFLAGS_gate.so = -shared -s -Wl,-soname=linux-gate.so.1 \
-                    $(call ld-option, -Wl$(comma)--hash-style=sysv)
- $(obj)/gate.so: $(obj)/gate.lds $(obj)/gate.o FORCE
-       $(call if_changed,gate)
- $(obj)/built-in.o: $(obj)/gate-syms.o
- $(obj)/built-in.o: ld_flags += -R $(obj)/gate-syms.o
- GATECFLAGS_gate-syms.o = -r
- $(obj)/gate-syms.o: $(obj)/gate.lds $(obj)/gate.o FORCE
-       $(call if_changed,gate)
- # gate-data.o contains the gate DSO image as data in section .data.gate.
- # We must build gate.so before we can assemble it.
- # Note: kbuild does not track this dependency due to usage of .incbin
- $(obj)/gate-data.o: $(obj)/gate.so
+ # The gate DSO image is built using a special linker script.
+ include $(srctree)/arch/ia64/kernel/Makefile.gate
+ # tell compiled for native
+ CPPFLAGS_gate.lds += -D__IA64_GATE_PARAVIRTUALIZED_NATIVE
  
  # Calculate NR_IRQ = max(IA64_NATIVE_NR_IRQS, XEN_NR_IRQS, ...) based on config
  define sed-y
@@@ -109,9 -90,9 +88,9 @@@ include/asm-ia64/nr-irqs.h: arch/$(SRCA
  clean-files += $(objtree)/include/asm-ia64/nr-irqs.h
  
  #
- # native ivt.S and entry.S
+ # native ivt.S, entry.S and fsys.S
  #
- ASM_PARAVIRT_OBJS = ivt.o entry.o
+ ASM_PARAVIRT_OBJS = ivt.o entry.o fsys.o
  define paravirtualized_native
  AFLAGS_$(1) += -D__IA64_ASM_PARAVIRTUALIZED_NATIVE
  AFLAGS_pvchk-sed-$(1) += -D__IA64_ASM_PARAVIRTUALIZED_PVCHECK
diff --combined arch/ia64/kernel/setup.c
index ae9ec3dc76b89269eced105542b3a7497f5cbc53,4ed3e1c117e73b57ecb2815e49642e18d671f7de..833b3ef92779b634462a907cce1713ec8109c74d
@@@ -52,6 -52,7 +52,7 @@@
  #include <asm/meminit.h>
  #include <asm/page.h>
  #include <asm/paravirt.h>
+ #include <asm/paravirt_patch.h>
  #include <asm/patch.h>
  #include <asm/pgtable.h>
  #include <asm/processor.h>
@@@ -537,6 -538,7 +538,7 @@@ setup_arch (char **cmdline_p
        paravirt_arch_setup_early();
  
        ia64_patch_vtop((u64) __start___vtop_patchlist, (u64) __end___vtop_patchlist);
+       paravirt_patch_apply();
  
        *cmdline_p = __va(ia64_boot_param->command_line);
        strlcpy(boot_command_line, *cmdline_p, COMMAND_LINE_SIZE);
@@@ -730,10 -732,10 +732,10 @@@ static void 
  c_start (struct seq_file *m, loff_t *pos)
  {
  #ifdef CONFIG_SMP
 -      while (*pos < NR_CPUS && !cpu_isset(*pos, cpu_online_map))
 +      while (*pos < nr_cpu_ids && !cpu_online(*pos))
                ++*pos;
  #endif
 -      return *pos < NR_CPUS ? cpu_data(*pos) : NULL;
 +      return *pos < nr_cpu_ids ? cpu_data(*pos) : NULL;
  }
  
  static void *
index 3765efc5f96333d3a40df579c075f5e6e95a77eb,794d168bc8a4ed9e21f1067a3ffcde76ee18faae..4a95e86b9ac200bafd30ddca8b1d50be6aec5081
@@@ -169,6 -169,30 +169,30 @@@ SECTION
          __end___mckinley_e9_bundles = .;
        }
  
+ #if defined(CONFIG_PARAVIRT)
+   . = ALIGN(16);
+   .paravirt_bundles : AT(ADDR(.paravirt_bundles) - LOAD_OFFSET)
+       {
+         __start_paravirt_bundles = .;
+           *(.paravirt_bundles)
+         __stop_paravirt_bundles = .;
+       }
+   . = ALIGN(16);
+   .paravirt_insts : AT(ADDR(.paravirt_insts) - LOAD_OFFSET)
+       {
+         __start_paravirt_insts = .;
+           *(.paravirt_insts)
+         __stop_paravirt_insts = .;
+       }
+   . = ALIGN(16);
+   .paravirt_branches : AT(ADDR(.paravirt_branches) - LOAD_OFFSET)
+       {
+         __start_paravirt_branches = .;
+         *(.paravirt_branches)
+         __stop_paravirt_branches = .;
+       }
+ #endif
  #if defined(CONFIG_IA64_GENERIC)
    /* Machine Vector */
    . = ALIGN(16);
          __start_gate_section = .;
          *(.data.gate)
          __stop_gate_section = .;
+ #ifdef CONFIG_XEN
+         . = ALIGN(PAGE_SIZE);
+         __xen_start_gate_section = .;
+         *(.data.gate.xen)
+         __xen_stop_gate_section = .;
+ #endif
        }
    . = ALIGN(PAGE_SIZE);               /* make sure the gate page doesn't expose
                                 * kernel data
          { *(.data.cacheline_aligned) }
  
    /* Per-cpu data: */
 -  percpu : { } :percpu
    . = ALIGN(PERCPU_PAGE_SIZE);
 -  __phys_per_cpu_start = .;
 -  .data.percpu PERCPU_ADDR : AT(__phys_per_cpu_start - LOAD_OFFSET)
 -      {
 -              __per_cpu_start = .;
 -              *(.data.percpu)
 -              *(.data.percpu.shared_aligned)
 -              __per_cpu_end = .;
 -      }
 +  PERCPU_VADDR(PERCPU_ADDR, :percpu)
 +  __phys_per_cpu_start = __per_cpu_load;
    . = __phys_per_cpu_start + PERCPU_PAGE_SIZE;        /* ensure percpu data fits
                                                 * into percpu page size
                                                 */
diff --combined arch/ia64/kvm/kvm-ia64.c
index 076b00d1dbffe3696eecb5662726faa204478bad,0344c66644853aa25064dcb53b68bd516ea981fa..28af6a731bb8a26361a60650263a3c943ff7bb9f
@@@ -70,7 -70,7 +70,7 @@@ static void kvm_flush_icache(unsigned l
        int l;
  
        for (l = 0; l < (len + 32); l += 32)
-               ia64_fc(start + l);
+               ia64_fc((void *)(start + l));
  
        ia64_sync_i();
        ia64_srlz_i();
@@@ -182,7 -182,7 +182,7 @@@ int kvm_dev_ioctl_check_extension(long 
        switch (ext) {
        case KVM_CAP_IRQCHIP:
        case KVM_CAP_MP_STATE:
 -
 +      case KVM_CAP_IRQ_INJECT_STATUS:
                r = 1;
                break;
        case KVM_CAP_COALESCED_MMIO:
@@@ -314,7 -314,7 +314,7 @@@ static struct kvm_vcpu *lid_to_vcpu(str
        union ia64_lid lid;
        int i;
  
 -      for (i = 0; i < KVM_MAX_VCPUS; i++) {
 +      for (i = 0; i < kvm->arch.online_vcpus; i++) {
                if (kvm->vcpus[i]) {
                        lid.val = VCPU_LID(kvm->vcpus[i]);
                        if (lid.id == id && lid.eid == eid)
@@@ -388,7 -388,7 +388,7 @@@ static int handle_global_purge(struct k
  
        call_data.ptc_g_data = p->u.ptc_g_data;
  
 -      for (i = 0; i < KVM_MAX_VCPUS; i++) {
 +      for (i = 0; i < kvm->arch.online_vcpus; i++) {
                if (!kvm->vcpus[i] || kvm->vcpus[i]->arch.mp_state ==
                                                KVM_MP_STATE_UNINITIALIZED ||
                                        vcpu == kvm->vcpus[i])
@@@ -788,8 -788,6 +788,8 @@@ struct  kvm *kvm_arch_create_vm(void
                return ERR_PTR(-ENOMEM);
        kvm_init_vm(kvm);
  
 +      kvm->arch.online_vcpus = 0;
 +
        return kvm;
  
  }
@@@ -921,13 -919,7 +921,13 @@@ long kvm_arch_vm_ioctl(struct file *fil
                r = kvm_ioapic_init(kvm);
                if (r)
                        goto out;
 +              r = kvm_setup_default_irq_routing(kvm);
 +              if (r) {
 +                      kfree(kvm->arch.vioapic);
 +                      goto out;
 +              }
                break;
 +      case KVM_IRQ_LINE_STATUS:
        case KVM_IRQ_LINE: {
                struct kvm_irq_level irq_event;
  
                if (copy_from_user(&irq_event, argp, sizeof irq_event))
                        goto out;
                if (irqchip_in_kernel(kvm)) {
 +                      __s32 status;
                        mutex_lock(&kvm->lock);
 -                      kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID,
 +                      status = kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID,
                                    irq_event.irq, irq_event.level);
                        mutex_unlock(&kvm->lock);
 +                      if (ioctl == KVM_IRQ_LINE_STATUS) {
 +                              irq_event.status = status;
 +                              if (copy_to_user(argp, &irq_event,
 +                                                      sizeof irq_event))
 +                                      goto out;
 +                      }
                        r = 0;
                }
                break;
@@@ -1164,7 -1149,7 +1164,7 @@@ int kvm_arch_vcpu_init(struct kvm_vcpu 
  
                /*Initialize itc offset for vcpus*/
                itc_offset = 0UL - ia64_getreg(_IA64_REG_AR_ITC);
 -              for (i = 0; i < KVM_MAX_VCPUS; i++) {
 +              for (i = 0; i < kvm->arch.online_vcpus; i++) {
                        v = (struct kvm_vcpu *)((char *)vcpu +
                                        sizeof(struct kvm_vcpu_data) * i);
                        v->arch.itc_offset = itc_offset;
@@@ -1298,8 -1283,6 +1298,8 @@@ struct kvm_vcpu *kvm_arch_vcpu_create(s
                goto fail;
        }
  
 +      kvm->arch.online_vcpus++;
 +
        return vcpu;
  fail:
        return ERR_PTR(r);
@@@ -1320,8 -1303,8 +1320,8 @@@ int kvm_arch_vcpu_ioctl_set_fpu(struct 
        return -EINVAL;
  }
  
 -int kvm_arch_vcpu_ioctl_debug_guest(struct kvm_vcpu *vcpu,
 -              struct kvm_debug_guest *dbg)
 +int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
 +                                      struct kvm_guest_debug *dbg)
  {
        return -EINVAL;
  }
@@@ -1438,23 -1421,6 +1438,23 @@@ int kvm_arch_vcpu_ioctl_get_regs(struc
        return 0;
  }
  
 +int kvm_arch_vcpu_ioctl_get_stack(struct kvm_vcpu *vcpu,
 +                                struct kvm_ia64_vcpu_stack *stack)
 +{
 +      memcpy(stack, vcpu, sizeof(struct kvm_ia64_vcpu_stack));
 +      return 0;
 +}
 +
 +int kvm_arch_vcpu_ioctl_set_stack(struct kvm_vcpu *vcpu,
 +                                struct kvm_ia64_vcpu_stack *stack)
 +{
 +      memcpy(vcpu + 1, &stack->stack[0] + sizeof(struct kvm_vcpu),
 +             sizeof(struct kvm_ia64_vcpu_stack) - sizeof(struct kvm_vcpu));
 +
 +      vcpu->arch.exit_data = ((struct kvm_vcpu *)stack)->arch.exit_data;
 +      return 0;
 +}
 +
  void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu)
  {
  
  
  
  long kvm_arch_vcpu_ioctl(struct file *filp,
 -              unsigned int ioctl, unsigned long arg)
 +                       unsigned int ioctl, unsigned long arg)
  {
 -      return -EINVAL;
 +      struct kvm_vcpu *vcpu = filp->private_data;
 +      void __user *argp = (void __user *)arg;
 +      struct kvm_ia64_vcpu_stack *stack = NULL;
 +      long r;
 +
 +      switch (ioctl) {
 +      case KVM_IA64_VCPU_GET_STACK: {
 +              struct kvm_ia64_vcpu_stack __user *user_stack;
 +              void __user *first_p = argp;
 +
 +              r = -EFAULT;
 +              if (copy_from_user(&user_stack, first_p, sizeof(void *)))
 +                      goto out;
 +
 +              if (!access_ok(VERIFY_WRITE, user_stack,
 +                             sizeof(struct kvm_ia64_vcpu_stack))) {
 +                      printk(KERN_INFO "KVM_IA64_VCPU_GET_STACK: "
 +                             "Illegal user destination address for stack\n");
 +                      goto out;
 +              }
 +              stack = kzalloc(sizeof(struct kvm_ia64_vcpu_stack), GFP_KERNEL);
 +              if (!stack) {
 +                      r = -ENOMEM;
 +                      goto out;
 +              }
 +
 +              r = kvm_arch_vcpu_ioctl_get_stack(vcpu, stack);
 +              if (r)
 +                      goto out;
 +
 +              if (copy_to_user(user_stack, stack,
 +                               sizeof(struct kvm_ia64_vcpu_stack)))
 +                      goto out;
 +
 +              break;
 +      }
 +      case KVM_IA64_VCPU_SET_STACK: {
 +              struct kvm_ia64_vcpu_stack __user *user_stack;
 +              void __user *first_p = argp;
 +
 +              r = -EFAULT;
 +              if (copy_from_user(&user_stack, first_p, sizeof(void *)))
 +                      goto out;
 +
 +              if (!access_ok(VERIFY_READ, user_stack,
 +                          sizeof(struct kvm_ia64_vcpu_stack))) {
 +                      printk(KERN_INFO "KVM_IA64_VCPU_SET_STACK: "
 +                             "Illegal user address for stack\n");
 +                      goto out;
 +              }
 +              stack = kmalloc(sizeof(struct kvm_ia64_vcpu_stack), GFP_KERNEL);
 +              if (!stack) {
 +                      r = -ENOMEM;
 +                      goto out;
 +              }
 +              if (copy_from_user(stack, user_stack,
 +                                 sizeof(struct kvm_ia64_vcpu_stack)))
 +                      goto out;
 +
 +              r = kvm_arch_vcpu_ioctl_set_stack(vcpu, stack);
 +              break;
 +      }
 +
 +      default:
 +              r = -EINVAL;
 +      }
 +
 +out:
 +      kfree(stack);
 +      return r;
  }
  
  int kvm_arch_set_memory_region(struct kvm *kvm,
@@@ -1575,7 -1472,7 +1575,7 @@@ void kvm_arch_flush_shadow(struct kvm *
  }
  
  long kvm_arch_dev_ioctl(struct file *filp,
 -              unsigned int ioctl, unsigned long arg)
 +                      unsigned int ioctl, unsigned long arg)
  {
        return -EINVAL;
  }
@@@ -1840,7 -1737,7 +1840,7 @@@ struct kvm_vcpu *kvm_get_lowest_prio_vc
        struct kvm_vcpu *lvcpu = kvm->vcpus[0];
        int i;
  
 -      for (i = 1; i < KVM_MAX_VCPUS; i++) {
 +      for (i = 1; i < kvm->arch.online_vcpus; i++) {
                if (!kvm->vcpus[i])
                        continue;
                if (lvcpu->arch.xtp > kvm->vcpus[i]->arch.xtp)
diff --combined arch/ia64/kvm/vcpu.c
index d4d28050587883e0f708fb5f46ed9cdb4a7ae3da,6839a52f7a41eae84571b0d6a5f6b5b109279857..a18ee17b9192e01f3c3f1683817be3ae775e1ca7
@@@ -112,6 -112,7 +112,6 @@@ void switch_to_physical_rid(struct kvm_
        return;
  }
  
 -
  void switch_to_virtual_rid(struct kvm_vcpu *vcpu)
  {
        unsigned long psr;
@@@ -165,6 -166,8 +165,6 @@@ void switch_mm_mode(struct kvm_vcpu *vc
        return;
  }
  
 -
 -
  /*
   * In physical mode, insert tc/tr for region 0 and 4 uses
   * RID[0] and RID[4] which is for physical mode emulation.
@@@ -266,6 -269,7 +266,6 @@@ static inline unsigned long fph_index(s
        return rotate_reg(96, rrb_fr, (regnum - IA64_FIRST_ROTATING_FR));
  }
  
 -
  /*
   * The inverse of the above: given bspstore and the number of
   * registers, calculate ar.bsp.
@@@ -386,7 -390,7 +386,7 @@@ void set_rse_reg(struct kvm_pt_regs *re
                else
                        *rnat_addr = (*rnat_addr) & (~nat_mask);
  
-               ia64_setreg(_IA64_REG_AR_BSPSTORE, bspstore);
+               ia64_setreg(_IA64_REG_AR_BSPSTORE, (unsigned long)bspstore);
                ia64_setreg(_IA64_REG_AR_RNAT, rnat);
        }
        local_irq_restore(psr);
@@@ -807,15 -811,12 +807,15 @@@ static inline void vcpu_set_itm(struct 
  static void vcpu_set_itc(struct kvm_vcpu *vcpu, u64 val)
  {
        struct kvm_vcpu *v;
 +      struct kvm *kvm;
        int i;
        long itc_offset = val - ia64_getreg(_IA64_REG_AR_ITC);
        unsigned long vitv = VCPU(vcpu, itv);
  
 +      kvm = (struct kvm *)KVM_VM_BASE;
 +
        if (vcpu->vcpu_id == 0) {
 -              for (i = 0; i < KVM_MAX_VCPUS; i++) {
 +              for (i = 0; i < kvm->arch.online_vcpus; i++) {
                        v = (struct kvm_vcpu *)((char *)vcpu +
                                        sizeof(struct kvm_vcpu_data) * i);
                        VMX(v, itc_offset) = itc_offset;
@@@ -1038,6 -1039,8 +1038,6 @@@ u64 vcpu_tak(struct kvm_vcpu *vcpu, u6
        return key;
  }
  
 -
 -
  void kvm_thash(struct kvm_vcpu *vcpu, INST64 inst)
  {
        unsigned long thash, vadr;
        vcpu_set_gr(vcpu, inst.M46.r1, thash, 0);
  }
  
 -
  void kvm_ttag(struct kvm_vcpu *vcpu, INST64 inst)
  {
        unsigned long tag, vadr;
@@@ -1127,6 -1131,7 +1127,6 @@@ int vcpu_tpa(struct kvm_vcpu *vcpu, u6
        return IA64_NO_FAULT;
  }
  
 -
  int kvm_tpa(struct kvm_vcpu *vcpu, INST64 inst)
  {
        unsigned long r1, r3;
@@@ -1149,6 -1154,7 +1149,6 @@@ void kvm_tak(struct kvm_vcpu *vcpu, INS
        vcpu_set_gr(vcpu, inst.M46.r1, r1, 0);
  }
  
 -
  /************************************
   * Insert/Purge translation register/cache
   ************************************/
@@@ -1379,6 -1385,7 +1379,6 @@@ void kvm_mov_to_ar_reg(struct kvm_vcpu 
        vcpu_set_itc(vcpu, r2);
  }
  
 -
  void kvm_mov_from_ar_reg(struct kvm_vcpu *vcpu, INST64 inst)
  {
        unsigned long r1;
        r1 = vcpu_get_itc(vcpu);
        vcpu_set_gr(vcpu, inst.M31.r1, r1, 0);
  }
 +
  /**************************************************************************
 -  struct kvm_vcpu*protection key register access routines
 +  struct kvm_vcpu protection key register access routines
   **************************************************************************/
  
  unsigned long vcpu_get_pkr(struct kvm_vcpu *vcpu, unsigned long reg)
@@@ -1401,6 -1407,20 +1401,6 @@@ void vcpu_set_pkr(struct kvm_vcpu *vcpu
        ia64_set_pkr(reg, val);
  }
  
 -
 -unsigned long vcpu_get_itir_on_fault(struct kvm_vcpu *vcpu, unsigned long ifa)
 -{
 -      union ia64_rr rr, rr1;
 -
 -      rr.val = vcpu_get_rr(vcpu, ifa);
 -      rr1.val = 0;
 -      rr1.ps = rr.ps;
 -      rr1.rid = rr.rid;
 -      return (rr1.val);
 -}
 -
 -
 -
  /********************************
   * Moves to privileged registers
   ********************************/
@@@ -1444,6 -1464,8 +1444,6 @@@ unsigned long vcpu_set_rr(struct kvm_vc
        return (IA64_NO_FAULT);
  }
  
 -
 -
  void kvm_mov_to_rr(struct kvm_vcpu *vcpu, INST64 inst)
  {
        unsigned long r3, r2;
@@@ -1488,6 -1510,8 +1488,6 @@@ void kvm_mov_to_pkr(struct kvm_vcpu *vc
        vcpu_set_pkr(vcpu, r3, r2);
  }
  
 -
 -
  void kvm_mov_from_rr(struct kvm_vcpu *vcpu, INST64 inst)
  {
        unsigned long r3, r1;
@@@ -1533,6 -1557,7 +1533,6 @@@ void kvm_mov_from_pmc(struct kvm_vcpu *
        vcpu_set_gr(vcpu, inst.M43.r1, r1, 0);
  }
  
 -
  unsigned long vcpu_get_cpuid(struct kvm_vcpu *vcpu, unsigned long reg)
  {
        /* FIXME: This could get called as a result of a rsvd-reg fault */
@@@ -1584,6 -1609,7 +1584,6 @@@ unsigned long kvm_mov_to_cr(struct kvm_
        return 0;
  }
  
 -
  unsigned long kvm_mov_from_cr(struct kvm_vcpu *vcpu, INST64 inst)
  {
        unsigned long tgt = inst.M33.r1;
        return 0;
  }
  
 -
 -
  void vcpu_set_psr(struct kvm_vcpu *vcpu, unsigned long val)
  {
  
@@@ -1748,6 -1776,9 +1748,6 @@@ void vcpu_bsw1(struct kvm_vcpu *vcpu
        }
  }
  
 -
 -
 -
  void vcpu_rfi(struct kvm_vcpu *vcpu)
  {
        unsigned long ifs, psr;
        regs->cr_iip = VCPU(vcpu, iip);
  }
  
 -
  /*
     VPSR can't keep track of below bits of guest PSR
     This function gets guest PSR
diff --combined arch/ia64/kvm/vtlb.c
index 38232b37668b3be87e8c8404aac2caea282bcc67,1de4dbda37e7dcaa9a31b6abe17a9e388dd048ee..2c2501f131597c6389e82e6c4e3e62eb6ecf7f80
@@@ -164,11 -164,11 +164,11 @@@ static void vhpt_insert(u64 pte, u64 it
        unsigned long ps, gpaddr;
  
        ps = itir_ps(itir);
 +      rr.val = ia64_get_rr(ifa);
  
 -      gpaddr = ((gpte & _PAGE_PPN_MASK) >> ps << ps) |
 -              (ifa & ((1UL << ps) - 1));
 +       gpaddr = ((gpte & _PAGE_PPN_MASK) >> ps << ps) |
 +                                      (ifa & ((1UL << ps) - 1));
  
 -      rr.val = ia64_get_rr(ifa);
        head = (struct thash_data *)ia64_thash(ifa);
        head->etag = INVALID_TI_TAG;
        ia64_mf();
@@@ -210,6 -210,7 +210,7 @@@ void thash_vhpt_insert(struct kvm_vcpu 
                phy_pte  &= ~PAGE_FLAGS_RV_MASK;
                psr = ia64_clear_ic();
                ia64_itc(type, va, phy_pte, itir_ps(itir));
+               paravirt_dv_serialize_data();
                ia64_set_psr(psr);
        }
  
@@@ -412,14 -413,16 +413,14 @@@ u64 translate_phy_pte(u64 *pte, u64 iti
  
  /*
   * Purge overlap TCs and then insert the new entry to emulate itc ops.
 - *    Notes: Only TC entry can purge and insert.
 - *    1 indicates this is MMIO
 + * Notes: Only TC entry can purge and insert.
   */
 -int thash_purge_and_insert(struct kvm_vcpu *v, u64 pte, u64 itir,
 +void  thash_purge_and_insert(struct kvm_vcpu *v, u64 pte, u64 itir,
                                                u64 ifa, int type)
  {
        u64 ps;
        u64 phy_pte, io_mask, index;
        union ia64_rr vrr, mrr;
 -      int ret = 0;
  
        ps = itir_ps(itir);
        vrr.val = vcpu_get_rr(v, ifa);
                phy_pte &= ~_PAGE_MA_MASK;
        }
  
 -      if (pte & VTLB_PTE_IO)
 -              ret = 1;
 -
        vtlb_purge(v, ifa, ps);
        vhpt_purge(v, ifa, ps);
  
 -      if (ps == mrr.ps) {
 -              if (!(pte&VTLB_PTE_IO)) {
 -                      vhpt_insert(phy_pte, itir, ifa, pte);
 -              } else {
 -                      vtlb_insert(v, pte, itir, ifa);
 -                      vcpu_quick_region_set(VMX(v, tc_regions), ifa);
 -              }
 -      } else if (ps > mrr.ps) {
 +      if ((ps != mrr.ps) || (pte & VTLB_PTE_IO)) {
                vtlb_insert(v, pte, itir, ifa);
                vcpu_quick_region_set(VMX(v, tc_regions), ifa);
 -              if (!(pte&VTLB_PTE_IO))
 -                      vhpt_insert(phy_pte, itir, ifa, pte);
 -      } else {
 +      }
 +      if (pte & VTLB_PTE_IO)
 +              return;
 +
 +      if (ps >= mrr.ps)
 +              vhpt_insert(phy_pte, itir, ifa, pte);
 +      else {
                u64 psr;
                phy_pte  &= ~PAGE_FLAGS_RV_MASK;
                psr = ia64_clear_ic();
                ia64_itc(type, ifa, phy_pte, ps);
+               paravirt_dv_serialize_data();
                ia64_set_psr(psr);
        }
        if (!(pte&VTLB_PTE_IO))
                mark_pages_dirty(v, pte, ps);
  
 -      return ret;
  }
  
  /*
@@@ -500,6 -511,7 +502,6 @@@ void thash_purge_all(struct kvm_vcpu *v
        local_flush_tlb_all();
  }
  
 -
  /*
   * Lookup the hash table and its collision chain to find an entry
   * covering this address rid:va or the entry.
   * INPUT:
   *  in: TLB format for both VHPT & TLB.
   */
 -
  struct thash_data *vtlb_lookup(struct kvm_vcpu *v, u64 va, int is_data)
  {
        struct thash_data  *cch;
        return NULL;
  }
  
 -
  /*
   * Initialize internal control data before service.
   */
@@@ -561,10 -575,6 +563,10 @@@ void thash_init(struct thash_cb *hcb, u
  u64 kvm_get_mpt_entry(u64 gpfn)
  {
        u64 *base = (u64 *) KVM_P2M_BASE;
 +
 +      if (gpfn >= (KVM_P2M_SIZE >> 3))
 +              panic_vm(current_vcpu, "Invalid gpfn =%lx\n", gpfn);
 +
        return *(base + gpfn);
  }
  
@@@ -581,6 -591,7 +583,6 @@@ u64 kvm_gpa_to_mpa(u64 gpa
        return (pte >> PAGE_SHIFT << PAGE_SHIFT) | (gpa & ~PAGE_MASK);
  }
  
 -
  /*
   * Fetch guest bundle code.
   * INPUT:
@@@ -622,6 -633,7 +624,6 @@@ int fetch_code(struct kvm_vcpu *vcpu, u
        return IA64_NO_FAULT;
  }
  
 -
  void kvm_init_vhpt(struct kvm_vcpu *v)
  {
        v->arch.vhpt.num = VHPT_NUM_ENTRIES;