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

[Xen-changelog] [xen-unstable] [IA64] Vcpu hot-plug support



# HG changeset patch
# User awilliam@xxxxxxxxxxx
# Node ID 2c7c715ad1856d79e973da4f068a14302718fa5e
# Parent  8b81c4e82f3ecde6ba1f1cbf32712c0e39ba4420
[IA64] Vcpu hot-plug support

Handle SAL return.
Handle ptr.i/ptr.d

Signed-off-by: Tristan Gingold <tristan.gingold@xxxxxxxx>
---
 linux-2.6-xen-sparse/arch/ia64/kernel/irq_ia64.c |   13 +-
 xen/arch/ia64/xen/dom_fw.c                       |   31 +----
 xen/arch/ia64/xen/domain.c                       |  114 ++++++-------------
 xen/arch/ia64/xen/hypercall.c                    |   54 +++++----
 xen/arch/ia64/xen/privop.c                       |   16 +-
 xen/arch/ia64/xen/vcpu.c                         |  133 +++++++++++++++++++----
 xen/include/asm-ia64/dom_fw.h                    |   18 ++-
 xen/include/asm-ia64/domain.h                    |    7 +
 xen/include/asm-ia64/vcpu.h                      |    7 -
 9 files changed, 231 insertions(+), 162 deletions(-)

diff -r 8b81c4e82f3e -r 2c7c715ad185 
linux-2.6-xen-sparse/arch/ia64/kernel/irq_ia64.c
--- a/linux-2.6-xen-sparse/arch/ia64/kernel/irq_ia64.c  Sat Jun 03 14:42:13 
2006 -0600
+++ b/linux-2.6-xen-sparse/arch/ia64/kernel/irq_ia64.c  Sat Jun 03 14:48:42 
2006 -0600
@@ -279,7 +279,7 @@ static struct irqaction resched_irqactio
  * FIXME: MCA is not supported by far, and thus "nomca" boot param is
  * required.
  */
-void
+static void
 xen_register_percpu_irq (unsigned int irq, struct irqaction *action, int save)
 {
        char name[15];
@@ -360,6 +360,7 @@ void xen_smp_intr_init(void)
                .type = CALLBACKTYPE_event,
                .address = (unsigned long)&xen_event_callback,
        };
+       static cpumask_t registered_cpumask;
 
        if (!cpu)
                return;
@@ -367,9 +368,13 @@ void xen_smp_intr_init(void)
        /* This should be piggyback when setup vcpu guest context */
        BUG_ON(HYPERVISOR_callback_op(CALLBACKOP_register, &event));
 
-       for (i = 0; i < saved_irq_cnt; i++)
-               xen_register_percpu_irq(saved_percpu_irqs[i].irq,
-                       saved_percpu_irqs[i].action, 0);
+       if (!cpu_isset(cpu, registered_cpumask)) {
+               cpu_set(cpu, registered_cpumask);
+               for (i = 0; i < saved_irq_cnt; i++)
+                       xen_register_percpu_irq(saved_percpu_irqs[i].irq,
+                                               saved_percpu_irqs[i].action,
+                                               0);
+       }
 #endif /* CONFIG_SMP */
 }
 #endif /* CONFIG_XEN */
diff -r 8b81c4e82f3e -r 2c7c715ad185 xen/arch/ia64/xen/dom_fw.c
--- a/xen/arch/ia64/xen/dom_fw.c        Sat Jun 03 14:42:13 2006 -0600
+++ b/xen/arch/ia64/xen/dom_fw.c        Sat Jun 03 14:48:42 2006 -0600
@@ -136,25 +136,6 @@ unsigned long dom_fw_setup(struct domain
 
 /* the following heavily leveraged from linux/arch/ia64/hp/sim/fw-emu.c */
 
-/* Set IP and GR1 of not yet initialized vcpu.  */
-static void
-set_os_boot_rendez (struct domain *d, unsigned long pc, unsigned long gr1)
-{
-       struct vcpu *v;
-       int i;
-
-       printf ("set_os_boot_rendez: %lx %lx\n", pc, gr1);
-       for (i = 1; i < MAX_VIRT_CPUS; i++) {
-               v = d->vcpu[i];
-               if (v != NULL
-                   && !test_bit(_VCPUF_initialised, &v->vcpu_flags)) {
-                       struct pt_regs *regs = vcpu_regs (v);
-                       regs->cr_iip = pc;
-                       regs->r1 = gr1;
-               }
-       }
-}
-
 struct sal_ret_values
 sal_emulator (long index, unsigned long in1, unsigned long in2,
              unsigned long in3, unsigned long in4, unsigned long in5,
@@ -218,8 +199,11 @@ sal_emulator (long index, unsigned long 
                                   second vector is reserved.  */
                                status = -2;
                        }
-                       else
-                               set_os_boot_rendez (current->domain, in2, in3);
+                       else {
+                               struct domain *d = current->domain;
+                               d->arch.boot_rdv_ip = in2;
+                               d->arch.boot_rdv_r1 = in3;
+                       }
                }
                else
                        printf("*** CALLED SAL_SET_VECTORS %lu.  IGNORED...\n",
@@ -980,6 +964,11 @@ dom_fw_init (struct domain *d, const cha
        dom_fw_hypercall_patch (d, sal_ed->sal_proc, FW_HYPERCALL_SAL_CALL, 1);
        sal_ed->gp = 0;  // will be ignored
 
+       /* SAL return point.  */
+       d->arch.sal_return_addr = FW_HYPERCALL_SAL_RETURN_PADDR + start_mpaddr;
+       dom_fw_hypercall_patch (d, d->arch.sal_return_addr,
+                               FW_HYPERCALL_SAL_RETURN, 0);
+
        /* Fill an AP wakeup descriptor.  */
        sal_wakeup->type = SAL_DESC_AP_WAKEUP;
        sal_wakeup->mechanism = IA64_SAL_AP_EXTERNAL_INT;
diff -r 8b81c4e82f3e -r 2c7c715ad185 xen/arch/ia64/xen/domain.c
--- a/xen/arch/ia64/xen/domain.c        Sat Jun 03 14:42:13 2006 -0600
+++ b/xen/arch/ia64/xen/domain.c        Sat Jun 03 14:48:42 2006 -0600
@@ -73,6 +73,8 @@ unsigned long initrd_start = 0, initrd_e
 unsigned long initrd_start = 0, initrd_end = 0;
 extern unsigned long running_on_sim;
 
+extern char dom0_command_line[];
+
 #define IS_XEN_ADDRESS(d,a) ((a >= d->xen_vastart) && (a <= d->xen_vaend))
 
 /* FIXME: where these declarations should be there ? */
@@ -211,8 +213,7 @@ static void init_switch_stack(struct vcp
        sw->ar_fpsr = FPSR_DEFAULT;
        v->arch._thread.ksp = (unsigned long) sw - 16;
        // stay on kernel stack because may get interrupts!
-       // ia64_ret_from_clone (which b0 gets in new_thread) switches
-       // to user stack
+       // ia64_ret_from_clone switches to user stack
        v->arch._thread.on_ustack = 0;
        memset(v->arch._thread.fph,0,sizeof(struct ia64_fpreg)*96);
 }
@@ -268,6 +269,7 @@ int arch_set_info_guest(struct vcpu *v, 
 {
        struct pt_regs *regs = vcpu_regs (v);
        struct domain *d = v->domain;
+       unsigned long cmdline_addr;
 
        if ( test_bit(_VCPUF_initialised, &v->vcpu_flags) )
             return 0;
@@ -285,6 +287,7 @@ int arch_set_info_guest(struct vcpu *v, 
            build_physmap_table(d);
 
        *regs = c->regs;
+       cmdline_addr = 0;
        if (v == d->vcpu[0]) {
            /* Only for first vcpu.  */
            d->arch.sys_pgnr = c->sys_pgnr;
@@ -293,11 +296,28 @@ int arch_set_info_guest(struct vcpu *v, 
            d->arch.cmdline      = c->cmdline;
            d->shared_info->arch = c->shared;
 
+           if (!VMX_DOMAIN(v)) {
+                   const char *cmdline = d->arch.cmdline;
+                   int len;
+
+                   if (*cmdline == 0) {
+#define DEFAULT_CMDLINE "nomca nosmp xencons=tty0 console=tty0 root=/dev/hda1"
+                           cmdline = DEFAULT_CMDLINE;
+                           len = sizeof (DEFAULT_CMDLINE);
+                           printf("domU command line defaulted to"
+                                  DEFAULT_CMDLINE "\n");
+                   }
+                   else
+                           len = IA64_COMMAND_LINE_SIZE;
+                   cmdline_addr = dom_fw_setup (d, cmdline, len);
+           }
+
            /* Cache synchronization seems to be done by the linux kernel
               during mmap/unmap operation.  However be conservative.  */
            domain_cache_flush (d, 1);
        }
-       new_thread(v, regs->cr_iip, 0, 0);
+       vcpu_init_regs (v);
+       regs->r28 = cmdline_addr;
 
        if ( c->privregs && copy_from_user(v->arch.privregs,
                           c->privregs, sizeof(mapped_regs_t))) {
@@ -305,8 +325,6 @@ int arch_set_info_guest(struct vcpu *v, 
                   c->privregs);
            return -EFAULT;
        }
-
-       v->arch.domain_itm_last = -1L;
 
        /* Don't redo final setup */
        set_bit(_VCPUF_initialised, &v->vcpu_flags);
@@ -391,79 +409,6 @@ void domain_relinquish_resources(struct 
 
     relinquish_memory(d, &d->xenpage_list);
     relinquish_memory(d, &d->page_list);
-}
-
-// heavily leveraged from linux/arch/ia64/kernel/process.c:copy_thread()
-// and linux/arch/ia64/kernel/process.c:kernel_thread()
-void new_thread(struct vcpu *v,
-                unsigned long start_pc,
-                unsigned long start_stack,
-                unsigned long start_info)
-{
-       struct domain *d = v->domain;
-       struct pt_regs *regs;
-       extern char dom0_command_line[];
-
-#ifdef CONFIG_DOMAIN0_CONTIGUOUS
-       if (d == dom0 && v->vcpu_id == 0) start_pc += dom0_start;
-#endif
-
-       regs = vcpu_regs (v);
-       if (VMX_DOMAIN(v)) {
-               /* dt/rt/it:1;i/ic:1, si:1, vm/bn:1, ac:1 */
-               regs->cr_ipsr = 0x501008826008; /* Need to be expanded as macro 
*/
-       } else {
-               regs->cr_ipsr = ia64_getreg(_IA64_REG_PSR)
-                 | IA64_PSR_BITS_TO_SET | IA64_PSR_BN;
-               regs->cr_ipsr &= ~(IA64_PSR_BITS_TO_CLEAR
-                                  | IA64_PSR_RI | IA64_PSR_IS);
-               regs->cr_ipsr |= 2UL << IA64_PSR_CPL0_BIT; // domain runs at PL2
-       }
-       regs->cr_iip = start_pc;
-       regs->cr_ifs = 1UL << 63; /* or clear? */
-       regs->ar_fpsr = FPSR_DEFAULT;
-
-       if (VMX_DOMAIN(v)) {
-               vmx_init_all_rr(v);
-               if (d == dom0)
-                   regs->r28 = dom_fw_setup(d,dom0_command_line,
-                                            COMMAND_LINE_SIZE);
-               /* Virtual processor context setup */
-               VCPU(v, vpsr) = IA64_PSR_BN;
-               VCPU(v, dcr) = 0;
-       } else {
-               init_all_rr(v);
-               if (v->vcpu_id == 0) {
-                       /* Build the firmware.  */
-                       if (d == dom0) 
-                               regs->r28 = dom_fw_setup(d,dom0_command_line,
-                                                        COMMAND_LINE_SIZE);
-                       else {
-                               const char *cmdline = d->arch.cmdline;
-                               int len;
-
-                               if (*cmdline == 0) {
-#define DEFAULT_CMDLINE "nomca nosmp xencons=tty0 console=tty0 root=/dev/hda1"
-                                       cmdline = DEFAULT_CMDLINE;
-                                       len = sizeof (DEFAULT_CMDLINE);
-                                       printf("domU command line defaulted to"
-                                              DEFAULT_CMDLINE "\n");
-                               }
-                               else
-                                       len = IA64_COMMAND_LINE_SIZE;
-
-                               regs->r28 = dom_fw_setup (d, cmdline, len);
-                       }
-                       d->shared_info->arch.flags = (d == dom0) ?
-                               (SIF_INITDOMAIN|SIF_PRIVILEGED) : 0;
-               }
-               regs->ar_rsc |= (2 << 2); /* force PL2/3 */
-               VCPU(v, banknum) = 1;
-               VCPU(v, metaphysical_mode) = 1;
-               VCPU(v, interrupt_mask_addr) =
-                   (uint64_t)SHAREDINFO_ADDR + INT_ENABLE_OFFSET(v);
-               VCPU(v, itv) = (1 << 16); /* timer vector masked */
-       }
 }
 
 void build_physmap_table(struct domain *d)
@@ -658,6 +603,7 @@ int construct_dom0(struct domain *d,
        unsigned long pkern_end;
        unsigned long pinitrd_start = 0;
        unsigned long pstart_info;
+       unsigned long cmdline_addr;
        struct page_info *start_info_page;
 
 #ifdef VALIDATE_VT
@@ -807,6 +753,7 @@ int construct_dom0(struct domain *d,
        //if ( initrd_len != 0 )
        //    memcpy((void *)vinitrd_start, initrd_start, initrd_len);
 
+       d->shared_info->arch.flags = SIF_INITDOMAIN|SIF_PRIVILEGED;
 
        /* Set up start info area. */
        d->shared_info->arch.start_info_pfn = pstart_info >> PAGE_SHIFT;
@@ -831,7 +778,16 @@ int construct_dom0(struct domain *d,
 
        set_bit(_VCPUF_initialised, &v->vcpu_flags);
 
-       new_thread(v, pkern_entry, 0, 0);
+       cmdline_addr = dom_fw_setup(d, dom0_command_line, COMMAND_LINE_SIZE);
+
+       vcpu_init_regs (v);
+
+#ifdef CONFIG_DOMAIN0_CONTIGUOUS
+       pkern_entry += dom0_start;
+#endif
+       vcpu_regs (v)->cr_iip = pkern_entry;
+       vcpu_regs (v)->r28 = cmdline_addr;
+
        physdev_init_dom0(d);
 
        // dom0 doesn't need build_physmap_table()
diff -r 8b81c4e82f3e -r 2c7c715ad185 xen/arch/ia64/xen/hypercall.c
--- a/xen/arch/ia64/xen/hypercall.c     Sat Jun 03 14:42:13 2006 -0600
+++ b/xen/arch/ia64/xen/hypercall.c     Sat Jun 03 14:48:42 2006 -0600
@@ -132,40 +132,42 @@ fw_hypercall_ipi (struct pt_regs *regs)
        int cpu = regs->r14;
        int vector = regs->r15;
        struct vcpu *targ;
-                   
-       if (0 && vector == 254)
-               printf ("send_ipi from %d to %d vector=%d\n",
-                       current->vcpu_id, cpu, vector);
-
+       struct domain *d = current->domain;
+
+       /* Be sure the target exists.  */
        if (cpu > MAX_VIRT_CPUS)
                return;
-
-       targ = current->domain->vcpu[cpu];
+       targ = d->vcpu[cpu];
        if (targ == NULL)
                return;
 
-       if (vector == XEN_SAL_BOOT_RENDEZ_VEC
-           && !test_bit(_VCPUF_initialised, &targ->vcpu_flags)) {
-               struct pt_regs *targ_regs = vcpu_regs (targ);
-               struct vcpu_guest_context c;
+       if (vector == XEN_SAL_BOOT_RENDEZ_VEC
+           && (!test_bit(_VCPUF_initialised, &targ->vcpu_flags)
+               || test_bit(_VCPUF_down, &targ->vcpu_flags))) {
+
+               /* First start: initialize vpcu.  */
+               if (!test_bit(_VCPUF_initialised, &targ->vcpu_flags)) {
+                       struct vcpu_guest_context c;
                
-               printf ("arch_boot_vcpu: %p %p\n",
-                       (void *)targ_regs->cr_iip,
-                       (void *)targ_regs->r1);
-               memset (&c, 0, sizeof (c));
-               /* Copy regs.  */
-               c.regs.cr_iip = targ_regs->cr_iip;
-               c.regs.r1 = targ_regs->r1;
-               
-               if (arch_set_info_guest (targ, &c) != 0) {
-                       printf ("arch_boot_vcpu: failure\n");
-                       return;
+                       memset (&c, 0, sizeof (c));
+
+                       if (arch_set_info_guest (targ, &c) != 0) {
+                               printf ("arch_boot_vcpu: failure\n");
+                               return;
+                       }
                }
+                       
+               /* First or next rendez-vous: set registers.  */
+               vcpu_init_regs (targ);
+               vcpu_regs (targ)->cr_iip = d->arch.boot_rdv_ip;
+               vcpu_regs (targ)->r1 = d->arch.boot_rdv_r1;
+               vcpu_regs (targ)->b0 = d->arch.sal_return_addr;
+
                if (test_and_clear_bit(_VCPUF_down,
                                       &targ->vcpu_flags)) {
                        vcpu_wake(targ);
-                       printf ("arch_boot_vcpu: vcpu %d awaken %016lx!\n",
-                               targ->vcpu_id, targ_regs->cr_iip);
+                       printf ("arch_boot_vcpu: vcpu %d awaken\n",
+                               targ->vcpu_id);
                }
                else
                        printf ("arch_boot_vcpu: huu, already awaken!\n");
@@ -253,6 +255,10 @@ fw_hypercall (struct pt_regs *regs)
                regs->r8 = x.r8; regs->r9 = x.r9;
                regs->r10 = x.r10; regs->r11 = x.r11;
                break;
+           case FW_HYPERCALL_SAL_RETURN:
+               if ( !test_and_set_bit(_VCPUF_down, &v->vcpu_flags) )
+                       vcpu_sleep_nosync(v);
+               break;
            case FW_HYPERCALL_EFI_CALL:
                efi_ret_value = efi_emulator (regs, &fault);
                if (fault != IA64_NO_FAULT) return fault;
diff -r 8b81c4e82f3e -r 2c7c715ad185 xen/arch/ia64/xen/privop.c
--- a/xen/arch/ia64/xen/privop.c        Sat Jun 03 14:42:13 2006 -0600
+++ b/xen/arch/ia64/xen/privop.c        Sat Jun 03 14:48:42 2006 -0600
@@ -166,19 +166,19 @@ IA64FAULT priv_ptr_d(VCPU *vcpu, INST64 
 IA64FAULT priv_ptr_d(VCPU *vcpu, INST64 inst)
 {
        UINT64 vadr = vcpu_get_gr(vcpu,inst.M45.r3);
-       UINT64 addr_range;
-
-       addr_range = 1 << ((vcpu_get_gr(vcpu,inst.M45.r2) & 0xfc) >> 2);
-       return vcpu_ptr_d(vcpu,vadr,addr_range);
+       UINT64 log_range;
+
+       log_range = (vcpu_get_gr(vcpu,inst.M45.r2) & 0xfc) >> 2;
+       return vcpu_ptr_d(vcpu,vadr,log_range);
 }
 
 IA64FAULT priv_ptr_i(VCPU *vcpu, INST64 inst)
 {
        UINT64 vadr = vcpu_get_gr(vcpu,inst.M45.r3);
-       UINT64 addr_range;
-
-       addr_range = 1 << ((vcpu_get_gr(vcpu,inst.M45.r2) & 0xfc) >> 2);
-       return vcpu_ptr_i(vcpu,vadr,addr_range);
+       UINT64 log_range;
+
+       log_range = (vcpu_get_gr(vcpu,inst.M45.r2) & 0xfc) >> 2;
+       return vcpu_ptr_i(vcpu,vadr,log_range);
 }
 
 IA64FAULT priv_tpa(VCPU *vcpu, INST64 inst)
diff -r 8b81c4e82f3e -r 2c7c715ad185 xen/arch/ia64/xen/vcpu.c
--- a/xen/arch/ia64/xen/vcpu.c  Sat Jun 03 14:42:13 2006 -0600
+++ b/xen/arch/ia64/xen/vcpu.c  Sat Jun 03 14:48:42 2006 -0600
@@ -143,6 +143,45 @@ vcpu_set_gr(VCPU *vcpu, unsigned long re
 }
 
 #endif
+
+void vcpu_init_regs (struct vcpu *v)
+{
+       struct pt_regs *regs;
+
+       regs = vcpu_regs (v);
+       if (VMX_DOMAIN(v)) {
+               /* dt/rt/it:1;i/ic:1, si:1, vm/bn:1, ac:1 */
+               /* Need to be expanded as macro */
+               regs->cr_ipsr = 0x501008826008;
+       } else {
+               regs->cr_ipsr = ia64_getreg(_IA64_REG_PSR)
+                 | IA64_PSR_BITS_TO_SET | IA64_PSR_BN;
+               regs->cr_ipsr &= ~(IA64_PSR_BITS_TO_CLEAR
+                                  | IA64_PSR_RI | IA64_PSR_IS);
+               // domain runs at PL2
+               regs->cr_ipsr |= 2UL << IA64_PSR_CPL0_BIT;
+       }
+       regs->cr_ifs = 1UL << 63; /* or clear? */
+       regs->ar_fpsr = FPSR_DEFAULT;
+
+       if (VMX_DOMAIN(v)) {
+               vmx_init_all_rr(v);
+               /* Virtual processor context setup */
+               VCPU(v, vpsr) = IA64_PSR_BN;
+               VCPU(v, dcr) = 0;
+       } else {
+               init_all_rr(v);
+               regs->ar_rsc |= (2 << 2); /* force PL2/3 */
+               VCPU(v, banknum) = 1;
+               VCPU(v, metaphysical_mode) = 1;
+               VCPU(v, interrupt_mask_addr) =
+                   (uint64_t)SHAREDINFO_ADDR + INT_ENABLE_OFFSET(v);
+               VCPU(v, itv) = (1 << 16); /* timer vector masked */
+       }
+
+       v->arch.domain_itm_last = -1L;
+}
+
 /**************************************************************************
  VCPU privileged application register access routines
 **************************************************************************/
@@ -1303,6 +1342,12 @@ unsigned long recover_to_break_fault_cou
 
 int warn_region0_address = 0; // FIXME later: tie to a boot parameter?
 
+/* Return TRUE iff [b1,e1] and [b2,e2] partially or fully overlaps.  */
+static inline int range_overlap (u64 b1, u64 e1, u64 b2, u64 e2)
+{
+       return (b1 <= e2) && (e1 >= b2);
+}
+
 // FIXME: also need to check && (!trp->key || vcpu_pkr_match(trp->key))
 static inline int vcpu_match_tr_entry_no_p(TR_ENTRY *trp, UINT64 ifa, UINT64 
rid)
 {
@@ -1314,6 +1359,16 @@ static inline int vcpu_match_tr_entry(TR
 static inline int vcpu_match_tr_entry(TR_ENTRY *trp, UINT64 ifa, UINT64 rid)
 {
        return trp->pte.p && vcpu_match_tr_entry_no_p(trp, ifa, rid);
+}
+
+static inline int
+vcpu_match_tr_entry_range(TR_ENTRY *trp, UINT64 rid, u64 b, u64 e)
+{
+       return trp->rid == rid
+               && trp->pte.p
+               && range_overlap (b, e,
+                                 trp->vadr, trp->vadr + (1L << trp->ps) - 1);
+
 }
 
 static TR_ENTRY*
@@ -1443,8 +1498,8 @@ IA64FAULT vcpu_translate(VCPU *vcpu, UIN
                         * region=5,VMM need to handle this tlb miss as if
                         * PSCB(vcpu,metaphysical_mode)=0
                         */           
-                       printk("vcpu_translate: bad physical address: 0x%lx\n",
-                              address);
+                       printk("vcpu_translate: bad physical address: 0x%lx at 
%lx\n",
+                              address, vcpu_regs (vcpu)->cr_iip);
 
                } else {
                        *pteval = (address & _PAGE_PPN_MASK) | __DIRTY_BITS |
@@ -1877,8 +1932,6 @@ IA64FAULT vcpu_itr_i(VCPU *vcpu, UINT64 
  VCPU translation cache access routines
 **************************************************************************/
 
-void foobar(void) { /*vcpu_verbose = 1;*/ }
-
 void vcpu_itc_no_srlz(VCPU *vcpu, UINT64 IorD, UINT64 vaddr, UINT64 pte, 
UINT64 mp_pte, UINT64 logps)
 {
        unsigned long psr;
@@ -1967,11 +2020,12 @@ IA64FAULT vcpu_ptc_l(VCPU *vcpu, UINT64 
        vcpu_purge_tr_entry(&PSCBX(vcpu,dtlb));
        vcpu_purge_tr_entry(&PSCBX(vcpu,itlb));
        
-       /*Purge all tlb and vhpt*/
+       /* Purge all tlb and vhpt */
        vcpu_flush_tlb_vhpt_range (vadr, log_range);
 
        return IA64_NO_FAULT;
 }
+
 // At privlvl=0, fc performs no access rights or protection key checks, while
 // at privlvl!=0, fc performs access rights checks as if it were a 1-byte
 // read but no protection key check.  Thus in order to avoid an unexpected
@@ -2021,16 +2075,59 @@ IA64FAULT vcpu_ptc_ga(VCPU *vcpu,UINT64 
        return IA64_NO_FAULT;
 }
 
-IA64FAULT vcpu_ptr_d(VCPU *vcpu,UINT64 vadr,UINT64 addr_range)
-{
-       printf("vcpu_ptr_d: Purging TLB is unsupported\n");
-       // don't forget to recompute dtr_regions
-       return (IA64_ILLOP_FAULT);
-}
-
-IA64FAULT vcpu_ptr_i(VCPU *vcpu,UINT64 vadr,UINT64 addr_range)
-{
-       printf("vcpu_ptr_i: Purging TLB is unsupported\n");
-       // don't forget to recompute itr_regions
-       return (IA64_ILLOP_FAULT);
-}
+IA64FAULT vcpu_ptr_d(VCPU *vcpu,UINT64 vadr,UINT64 log_range)
+{
+       unsigned long region = vadr >> 61;
+       u64 addr_range = 1UL << log_range;
+       unsigned long rid, rr;
+       int i;
+       TR_ENTRY *trp;
+
+       rr = PSCB(vcpu,rrs)[region];
+       rid = rr & RR_RID_MASK;
+
+       /* Purge TC  */
+       vcpu_purge_tr_entry(&PSCBX(vcpu,dtlb));
+
+       /* Purge tr and recompute dtr_regions.  */
+       vcpu->arch.dtr_regions = 0;
+       for (trp = vcpu->arch.dtrs, i = NDTRS; i; i--, trp++)
+               if (vcpu_match_tr_entry_range (trp,rid, vadr, vadr+addr_range))
+                       vcpu_purge_tr_entry(trp);
+               else if (trp->pte.p)
+                       vcpu_quick_region_set(vcpu->arch.dtr_regions,
+                                             trp->vadr);
+
+       vcpu_flush_tlb_vhpt_range (vadr, log_range);
+
+       return IA64_NO_FAULT;
+}
+
+IA64FAULT vcpu_ptr_i(VCPU *vcpu,UINT64 vadr,UINT64 log_range)
+{
+       unsigned long region = vadr >> 61;
+       u64 addr_range = 1UL << log_range;
+       unsigned long rid, rr;
+       int i;
+       TR_ENTRY *trp;
+
+       rr = PSCB(vcpu,rrs)[region];
+       rid = rr & RR_RID_MASK;
+
+       /* Purge TC  */
+       vcpu_purge_tr_entry(&PSCBX(vcpu,itlb));
+
+       /* Purge tr and recompute itr_regions.  */
+       vcpu->arch.itr_regions = 0;
+       for (trp = vcpu->arch.itrs, i = NITRS; i; i--, trp++)
+               if (vcpu_match_tr_entry_range (trp,rid, vadr, vadr+addr_range))
+                       vcpu_purge_tr_entry(trp);
+               else if (trp->pte.p)
+                       vcpu_quick_region_set(vcpu->arch.itr_regions,
+                                             trp->vadr);
+
+
+       vcpu_flush_tlb_vhpt_range (vadr, log_range);
+
+       return IA64_NO_FAULT;
+}
diff -r 8b81c4e82f3e -r 2c7c715ad185 xen/include/asm-ia64/dom_fw.h
--- a/xen/include/asm-ia64/dom_fw.h     Sat Jun 03 14:42:13 2006 -0600
+++ b/xen/include/asm-ia64/dom_fw.h     Sat Jun 03 14:48:42 2006 -0600
@@ -20,6 +20,11 @@
 #define FW_HYPERCALL_BASE_PADDR HYPERCALL_START
 #define        FW_HYPERCALL_END_PADDR HYPERCALL_END
 #define        FW_HYPERCALL_PADDR(index) (FW_HYPERCALL_BASE_PADDR + (16UL * 
index))
+
+/* Hypercalls number have a low part and a high part.
+   The high part is the class (xen/pal/sal/efi).  */
+#define FW_HYPERCALL_NUM_MASK_HIGH     ~0xffUL
+#define FW_HYPERCALL_NUM_MASK_LOW       0xffUL
 
 /*
  * PAL can be called in physical or virtual mode simply by
@@ -57,6 +62,11 @@
 #define FW_HYPERCALL_SAL_CALL_PADDR    
FW_HYPERCALL_PADDR(FW_HYPERCALL_SAL_CALL_INDEX)
 #define FW_HYPERCALL_SAL_CALL          0x1100UL
 
+/* SAL return point.  */
+#define FW_HYPERCALL_SAL_RETURN_INDEX  0x84UL
+#define FW_HYPERCALL_SAL_RETURN_PADDR  
FW_HYPERCALL_PADDR(FW_HYPERCALL_SAL_RETURN_INDEX)
+#define FW_HYPERCALL_SAL_RETURN                0x1200UL
+
 /*
  * EFI is accessed via the EFI system table, which contains:
  * - a header which contains version info
@@ -81,7 +91,6 @@
  */
 
 /* these are indexes into the runtime services table */
-#define        FW_HYPERCALL_EFI_BASE
 #define FW_HYPERCALL_EFI_GET_TIME_INDEX                        0UL
 #define FW_HYPERCALL_EFI_SET_TIME_INDEX                        1UL
 #define FW_HYPERCALL_EFI_GET_WAKEUP_TIME_INDEX         2UL
@@ -130,8 +139,8 @@
  * This is a hypercall number for FPSWA.
  * FPSWA hypercall uses 2 bundles for a pseudo-entry-point and a 
hypercall-patch.
  */
-#define FW_HYPERCALL_FPSWA_ENTRY_INDEX                 0x83UL
-#define FW_HYPERCALL_FPSWA_PATCH_INDEX                 0x84UL
+#define FW_HYPERCALL_FPSWA_ENTRY_INDEX                 0x90UL
+#define FW_HYPERCALL_FPSWA_PATCH_INDEX                 0x91UL
 #define FW_HYPERCALL_FPSWA_ENTRY_PADDR                 
FW_HYPERCALL_PADDR(FW_HYPERCALL_FPSWA_ENTRY_INDEX)
 #define FW_HYPERCALL_FPSWA_PATCH_PADDR                 
FW_HYPERCALL_PADDR(FW_HYPERCALL_FPSWA_PATCH_INDEX)
 #define FW_HYPERCALL_FPSWA                             0x500UL
@@ -149,9 +158,6 @@
 /* Interrupt vector used for os boot rendez vous.  */
 #define XEN_SAL_BOOT_RENDEZ_VEC        0xF3
 
-#define FW_HYPERCALL_NUM_MASK_HIGH     ~0xffUL
-#define FW_HYPERCALL_NUM_MASK_LOW       0xffUL
-
 #define EFI_MEMDESC_VERSION            1
 
 extern struct ia64_pal_retval xen_pal_emulator(UINT64, u64, u64, u64);
diff -r 8b81c4e82f3e -r 2c7c715ad185 xen/include/asm-ia64/domain.h
--- a/xen/include/asm-ia64/domain.h     Sat Jun 03 14:42:13 2006 -0600
+++ b/xen/include/asm-ia64/domain.h     Sat Jun 03 14:48:42 2006 -0600
@@ -53,6 +53,13 @@ struct arch_domain {
     unsigned long max_pfn; /* Max pfn including I/O holes */
     struct virtual_platform_def     vmx_platform;
 #define        hvm_domain vmx_platform /* platform defs are not vmx specific */
+
+    /* OS boot rendez vous.  */
+    unsigned long boot_rdv_ip;
+    unsigned long boot_rdv_r1;
+
+    /* SAL return point.  */
+    unsigned long sal_return_addr;
 
     u64 xen_vastart;
     u64 xen_vaend;
diff -r 8b81c4e82f3e -r 2c7c715ad185 xen/include/asm-ia64/vcpu.h
--- a/xen/include/asm-ia64/vcpu.h       Sat Jun 03 14:42:13 2006 -0600
+++ b/xen/include/asm-ia64/vcpu.h       Sat Jun 03 14:48:42 2006 -0600
@@ -149,8 +149,8 @@ extern IA64FAULT vcpu_ptc_e(VCPU *vcpu, 
 extern IA64FAULT vcpu_ptc_e(VCPU *vcpu, UINT64 vadr);
 extern IA64FAULT vcpu_ptc_g(VCPU *vcpu, UINT64 vadr, UINT64 addr_range);
 extern IA64FAULT vcpu_ptc_ga(VCPU *vcpu, UINT64 vadr, UINT64 addr_range);
-extern IA64FAULT vcpu_ptr_d(VCPU *vcpu,UINT64 vadr, UINT64 addr_range);
-extern IA64FAULT vcpu_ptr_i(VCPU *vcpu,UINT64 vadr, UINT64 addr_range);
+extern IA64FAULT vcpu_ptr_d(VCPU *vcpu,UINT64 vadr, UINT64 log_range);
+extern IA64FAULT vcpu_ptr_i(VCPU *vcpu,UINT64 vadr, UINT64 log_range);
 union U_IA64_BUNDLE;
 extern int vcpu_get_domain_bundle(VCPU *vcpu, REGS *regs, UINT64 gip, union 
U_IA64_BUNDLE *bundle);
 extern IA64FAULT vcpu_translate(VCPU *vcpu, UINT64 address, BOOLEAN is_data,
@@ -176,6 +176,9 @@ extern UINT64 vcpu_get_tmp(VCPU *, UINT6
 extern UINT64 vcpu_get_tmp(VCPU *, UINT64);
 extern void vcpu_set_tmp(VCPU *, UINT64, UINT64);
 
+/* Initialize vcpu regs.  */
+extern void vcpu_init_regs (struct vcpu *v);
+
 static inline UINT64
 itir_ps(UINT64 itir)
 {

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

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