direct-io.hg

changeset 10374:2c7c715ad185

[IA64] Vcpu hot-plug support

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

Signed-off-by: Tristan Gingold <tristan.gingold@bull.net>
author awilliam@xenbuild.aw
date Sat Jun 03 14:48:42 2006 -0600 (2006-06-03)
parents 8b81c4e82f3e
children 976517433993
files linux-2.6-xen-sparse/arch/ia64/kernel/irq_ia64.c xen/arch/ia64/xen/dom_fw.c xen/arch/ia64/xen/domain.c xen/arch/ia64/xen/hypercall.c xen/arch/ia64/xen/privop.c xen/arch/ia64/xen/vcpu.c xen/include/asm-ia64/dom_fw.h xen/include/asm-ia64/domain.h xen/include/asm-ia64/vcpu.h
line diff
     1.1 --- a/linux-2.6-xen-sparse/arch/ia64/kernel/irq_ia64.c	Sat Jun 03 14:42:13 2006 -0600
     1.2 +++ b/linux-2.6-xen-sparse/arch/ia64/kernel/irq_ia64.c	Sat Jun 03 14:48:42 2006 -0600
     1.3 @@ -279,7 +279,7 @@ static struct irqaction resched_irqactio
     1.4   * FIXME: MCA is not supported by far, and thus "nomca" boot param is
     1.5   * required.
     1.6   */
     1.7 -void
     1.8 +static void
     1.9  xen_register_percpu_irq (unsigned int irq, struct irqaction *action, int save)
    1.10  {
    1.11  	char name[15];
    1.12 @@ -360,6 +360,7 @@ void xen_smp_intr_init(void)
    1.13  		.type = CALLBACKTYPE_event,
    1.14  		.address = (unsigned long)&xen_event_callback,
    1.15  	};
    1.16 +	static cpumask_t registered_cpumask;
    1.17  
    1.18  	if (!cpu)
    1.19  		return;
    1.20 @@ -367,9 +368,13 @@ void xen_smp_intr_init(void)
    1.21  	/* This should be piggyback when setup vcpu guest context */
    1.22  	BUG_ON(HYPERVISOR_callback_op(CALLBACKOP_register, &event));
    1.23  
    1.24 -	for (i = 0; i < saved_irq_cnt; i++)
    1.25 -		xen_register_percpu_irq(saved_percpu_irqs[i].irq,
    1.26 -			saved_percpu_irqs[i].action, 0);
    1.27 +	if (!cpu_isset(cpu, registered_cpumask)) {
    1.28 +		cpu_set(cpu, registered_cpumask);
    1.29 +		for (i = 0; i < saved_irq_cnt; i++)
    1.30 +			xen_register_percpu_irq(saved_percpu_irqs[i].irq,
    1.31 +						saved_percpu_irqs[i].action,
    1.32 +						0);
    1.33 +	}
    1.34  #endif /* CONFIG_SMP */
    1.35  }
    1.36  #endif /* CONFIG_XEN */
     2.1 --- a/xen/arch/ia64/xen/dom_fw.c	Sat Jun 03 14:42:13 2006 -0600
     2.2 +++ b/xen/arch/ia64/xen/dom_fw.c	Sat Jun 03 14:48:42 2006 -0600
     2.3 @@ -136,25 +136,6 @@ unsigned long dom_fw_setup(struct domain
     2.4  
     2.5  /* the following heavily leveraged from linux/arch/ia64/hp/sim/fw-emu.c */
     2.6  
     2.7 -/* Set IP and GR1 of not yet initialized vcpu.  */
     2.8 -static void
     2.9 -set_os_boot_rendez (struct domain *d, unsigned long pc, unsigned long gr1)
    2.10 -{
    2.11 -	struct vcpu *v;
    2.12 -	int i;
    2.13 -
    2.14 -	printf ("set_os_boot_rendez: %lx %lx\n", pc, gr1);
    2.15 -	for (i = 1; i < MAX_VIRT_CPUS; i++) {
    2.16 -		v = d->vcpu[i];
    2.17 -		if (v != NULL
    2.18 -		    && !test_bit(_VCPUF_initialised, &v->vcpu_flags)) {
    2.19 -			struct pt_regs *regs = vcpu_regs (v);
    2.20 -			regs->cr_iip = pc;
    2.21 -			regs->r1 = gr1;
    2.22 -		}
    2.23 -	}
    2.24 -}
    2.25 -
    2.26  struct sal_ret_values
    2.27  sal_emulator (long index, unsigned long in1, unsigned long in2,
    2.28  	      unsigned long in3, unsigned long in4, unsigned long in5,
    2.29 @@ -218,8 +199,11 @@ sal_emulator (long index, unsigned long 
    2.30   				   second vector is reserved.  */
    2.31   				status = -2;
    2.32   			}
    2.33 - 			else
    2.34 - 				set_os_boot_rendez (current->domain, in2, in3);
    2.35 + 			else {
    2.36 +				struct domain *d = current->domain;
    2.37 +				d->arch.boot_rdv_ip = in2;
    2.38 +				d->arch.boot_rdv_r1 = in3;
    2.39 +			}
    2.40   		}
    2.41   		else
    2.42   			printf("*** CALLED SAL_SET_VECTORS %lu.  IGNORED...\n",
    2.43 @@ -980,6 +964,11 @@ dom_fw_init (struct domain *d, const cha
    2.44  	dom_fw_hypercall_patch (d, sal_ed->sal_proc, FW_HYPERCALL_SAL_CALL, 1);
    2.45  	sal_ed->gp = 0;  // will be ignored
    2.46  
    2.47 +	/* SAL return point.  */
    2.48 +	d->arch.sal_return_addr = FW_HYPERCALL_SAL_RETURN_PADDR + start_mpaddr;
    2.49 +	dom_fw_hypercall_patch (d, d->arch.sal_return_addr,
    2.50 +				FW_HYPERCALL_SAL_RETURN, 0);
    2.51 +
    2.52  	/* Fill an AP wakeup descriptor.  */
    2.53  	sal_wakeup->type = SAL_DESC_AP_WAKEUP;
    2.54  	sal_wakeup->mechanism = IA64_SAL_AP_EXTERNAL_INT;
     3.1 --- a/xen/arch/ia64/xen/domain.c	Sat Jun 03 14:42:13 2006 -0600
     3.2 +++ b/xen/arch/ia64/xen/domain.c	Sat Jun 03 14:48:42 2006 -0600
     3.3 @@ -73,6 +73,8 @@ integer_param("dom0_max_vcpus", dom0_max
     3.4  unsigned long initrd_start = 0, initrd_end = 0;
     3.5  extern unsigned long running_on_sim;
     3.6  
     3.7 +extern char dom0_command_line[];
     3.8 +
     3.9  #define IS_XEN_ADDRESS(d,a) ((a >= d->xen_vastart) && (a <= d->xen_vaend))
    3.10  
    3.11  /* FIXME: where these declarations should be there ? */
    3.12 @@ -211,8 +213,7 @@ static void init_switch_stack(struct vcp
    3.13  	sw->ar_fpsr = FPSR_DEFAULT;
    3.14  	v->arch._thread.ksp = (unsigned long) sw - 16;
    3.15  	// stay on kernel stack because may get interrupts!
    3.16 -	// ia64_ret_from_clone (which b0 gets in new_thread) switches
    3.17 -	// to user stack
    3.18 +	// ia64_ret_from_clone switches to user stack
    3.19  	v->arch._thread.on_ustack = 0;
    3.20  	memset(v->arch._thread.fph,0,sizeof(struct ia64_fpreg)*96);
    3.21  }
    3.22 @@ -268,6 +269,7 @@ int arch_set_info_guest(struct vcpu *v, 
    3.23  {
    3.24  	struct pt_regs *regs = vcpu_regs (v);
    3.25  	struct domain *d = v->domain;
    3.26 +	unsigned long cmdline_addr;
    3.27  
    3.28  	if ( test_bit(_VCPUF_initialised, &v->vcpu_flags) )
    3.29              return 0;
    3.30 @@ -285,6 +287,7 @@ int arch_set_info_guest(struct vcpu *v, 
    3.31  	    build_physmap_table(d);
    3.32  
    3.33  	*regs = c->regs;
    3.34 +	cmdline_addr = 0;
    3.35  	if (v == d->vcpu[0]) {
    3.36  	    /* Only for first vcpu.  */
    3.37  	    d->arch.sys_pgnr = c->sys_pgnr;
    3.38 @@ -293,11 +296,28 @@ int arch_set_info_guest(struct vcpu *v, 
    3.39  	    d->arch.cmdline      = c->cmdline;
    3.40  	    d->shared_info->arch = c->shared;
    3.41  
    3.42 +	    if (!VMX_DOMAIN(v)) {
    3.43 +		    const char *cmdline = d->arch.cmdline;
    3.44 +		    int len;
    3.45 +
    3.46 +		    if (*cmdline == 0) {
    3.47 +#define DEFAULT_CMDLINE "nomca nosmp xencons=tty0 console=tty0 root=/dev/hda1"
    3.48 +			    cmdline = DEFAULT_CMDLINE;
    3.49 +			    len = sizeof (DEFAULT_CMDLINE);
    3.50 +			    printf("domU command line defaulted to"
    3.51 +				   DEFAULT_CMDLINE "\n");
    3.52 +		    }
    3.53 +		    else
    3.54 +			    len = IA64_COMMAND_LINE_SIZE;
    3.55 +		    cmdline_addr = dom_fw_setup (d, cmdline, len);
    3.56 +	    }
    3.57 +
    3.58  	    /* Cache synchronization seems to be done by the linux kernel
    3.59  	       during mmap/unmap operation.  However be conservative.  */
    3.60  	    domain_cache_flush (d, 1);
    3.61  	}
    3.62 -	new_thread(v, regs->cr_iip, 0, 0);
    3.63 +	vcpu_init_regs (v);
    3.64 +	regs->r28 = cmdline_addr;
    3.65  
    3.66  	if ( c->privregs && copy_from_user(v->arch.privregs,
    3.67  			   c->privregs, sizeof(mapped_regs_t))) {
    3.68 @@ -306,8 +326,6 @@ int arch_set_info_guest(struct vcpu *v, 
    3.69  	    return -EFAULT;
    3.70  	}
    3.71  
    3.72 -	v->arch.domain_itm_last = -1L;
    3.73 -
    3.74  	/* Don't redo final setup */
    3.75  	set_bit(_VCPUF_initialised, &v->vcpu_flags);
    3.76  	return 0;
    3.77 @@ -393,79 +411,6 @@ void domain_relinquish_resources(struct 
    3.78      relinquish_memory(d, &d->page_list);
    3.79  }
    3.80  
    3.81 -// heavily leveraged from linux/arch/ia64/kernel/process.c:copy_thread()
    3.82 -// and linux/arch/ia64/kernel/process.c:kernel_thread()
    3.83 -void new_thread(struct vcpu *v,
    3.84 -                unsigned long start_pc,
    3.85 -                unsigned long start_stack,
    3.86 -                unsigned long start_info)
    3.87 -{
    3.88 -	struct domain *d = v->domain;
    3.89 -	struct pt_regs *regs;
    3.90 -	extern char dom0_command_line[];
    3.91 -
    3.92 -#ifdef CONFIG_DOMAIN0_CONTIGUOUS
    3.93 -	if (d == dom0 && v->vcpu_id == 0) start_pc += dom0_start;
    3.94 -#endif
    3.95 -
    3.96 -	regs = vcpu_regs (v);
    3.97 -	if (VMX_DOMAIN(v)) {
    3.98 -		/* dt/rt/it:1;i/ic:1, si:1, vm/bn:1, ac:1 */
    3.99 -		regs->cr_ipsr = 0x501008826008; /* Need to be expanded as macro */
   3.100 -	} else {
   3.101 -		regs->cr_ipsr = ia64_getreg(_IA64_REG_PSR)
   3.102 -		  | IA64_PSR_BITS_TO_SET | IA64_PSR_BN;
   3.103 -		regs->cr_ipsr &= ~(IA64_PSR_BITS_TO_CLEAR
   3.104 -				   | IA64_PSR_RI | IA64_PSR_IS);
   3.105 -		regs->cr_ipsr |= 2UL << IA64_PSR_CPL0_BIT; // domain runs at PL2
   3.106 -	}
   3.107 -	regs->cr_iip = start_pc;
   3.108 -	regs->cr_ifs = 1UL << 63; /* or clear? */
   3.109 -	regs->ar_fpsr = FPSR_DEFAULT;
   3.110 -
   3.111 -	if (VMX_DOMAIN(v)) {
   3.112 -		vmx_init_all_rr(v);
   3.113 -		if (d == dom0)
   3.114 -		    regs->r28 = dom_fw_setup(d,dom0_command_line,
   3.115 -					     COMMAND_LINE_SIZE);
   3.116 -		/* Virtual processor context setup */
   3.117 -		VCPU(v, vpsr) = IA64_PSR_BN;
   3.118 -		VCPU(v, dcr) = 0;
   3.119 -	} else {
   3.120 -		init_all_rr(v);
   3.121 -		if (v->vcpu_id == 0) {
   3.122 -			/* Build the firmware.  */
   3.123 -			if (d == dom0) 
   3.124 -				regs->r28 = dom_fw_setup(d,dom0_command_line,
   3.125 -							 COMMAND_LINE_SIZE);
   3.126 -			else {
   3.127 -				const char *cmdline = d->arch.cmdline;
   3.128 -				int len;
   3.129 -
   3.130 -				if (*cmdline == 0) {
   3.131 -#define DEFAULT_CMDLINE "nomca nosmp xencons=tty0 console=tty0 root=/dev/hda1"
   3.132 -					cmdline = DEFAULT_CMDLINE;
   3.133 -					len = sizeof (DEFAULT_CMDLINE);
   3.134 -					printf("domU command line defaulted to"
   3.135 -					       DEFAULT_CMDLINE "\n");
   3.136 -				}
   3.137 -				else
   3.138 -					len = IA64_COMMAND_LINE_SIZE;
   3.139 -
   3.140 -				regs->r28 = dom_fw_setup (d, cmdline, len);
   3.141 -			}
   3.142 -			d->shared_info->arch.flags = (d == dom0) ?
   3.143 -				(SIF_INITDOMAIN|SIF_PRIVILEGED) : 0;
   3.144 -		}
   3.145 -		regs->ar_rsc |= (2 << 2); /* force PL2/3 */
   3.146 -		VCPU(v, banknum) = 1;
   3.147 -		VCPU(v, metaphysical_mode) = 1;
   3.148 -		VCPU(v, interrupt_mask_addr) =
   3.149 -		    (uint64_t)SHAREDINFO_ADDR + INT_ENABLE_OFFSET(v);
   3.150 -		VCPU(v, itv) = (1 << 16); /* timer vector masked */
   3.151 -	}
   3.152 -}
   3.153 -
   3.154  void build_physmap_table(struct domain *d)
   3.155  {
   3.156  	struct list_head *list_ent = d->page_list.next;
   3.157 @@ -658,6 +603,7 @@ int construct_dom0(struct domain *d,
   3.158  	unsigned long pkern_end;
   3.159  	unsigned long pinitrd_start = 0;
   3.160  	unsigned long pstart_info;
   3.161 +	unsigned long cmdline_addr;
   3.162  	struct page_info *start_info_page;
   3.163  
   3.164  #ifdef VALIDATE_VT
   3.165 @@ -807,6 +753,7 @@ int construct_dom0(struct domain *d,
   3.166  	//if ( initrd_len != 0 )
   3.167  	//    memcpy((void *)vinitrd_start, initrd_start, initrd_len);
   3.168  
   3.169 +	d->shared_info->arch.flags = SIF_INITDOMAIN|SIF_PRIVILEGED;
   3.170  
   3.171  	/* Set up start info area. */
   3.172  	d->shared_info->arch.start_info_pfn = pstart_info >> PAGE_SHIFT;
   3.173 @@ -831,7 +778,16 @@ int construct_dom0(struct domain *d,
   3.174  
   3.175  	set_bit(_VCPUF_initialised, &v->vcpu_flags);
   3.176  
   3.177 -	new_thread(v, pkern_entry, 0, 0);
   3.178 +	cmdline_addr = dom_fw_setup(d, dom0_command_line, COMMAND_LINE_SIZE);
   3.179 +
   3.180 +	vcpu_init_regs (v);
   3.181 +
   3.182 +#ifdef CONFIG_DOMAIN0_CONTIGUOUS
   3.183 +	pkern_entry += dom0_start;
   3.184 +#endif
   3.185 +	vcpu_regs (v)->cr_iip = pkern_entry;
   3.186 +	vcpu_regs (v)->r28 = cmdline_addr;
   3.187 +
   3.188  	physdev_init_dom0(d);
   3.189  
   3.190  	// dom0 doesn't need build_physmap_table()
     4.1 --- a/xen/arch/ia64/xen/hypercall.c	Sat Jun 03 14:42:13 2006 -0600
     4.2 +++ b/xen/arch/ia64/xen/hypercall.c	Sat Jun 03 14:48:42 2006 -0600
     4.3 @@ -132,40 +132,42 @@ fw_hypercall_ipi (struct pt_regs *regs)
     4.4  	int cpu = regs->r14;
     4.5  	int vector = regs->r15;
     4.6  	struct vcpu *targ;
     4.7 -		    
     4.8 -	if (0 && vector == 254)
     4.9 -		printf ("send_ipi from %d to %d vector=%d\n",
    4.10 -			current->vcpu_id, cpu, vector);
    4.11 +	struct domain *d = current->domain;
    4.12  
    4.13 +	/* Be sure the target exists.  */
    4.14  	if (cpu > MAX_VIRT_CPUS)
    4.15  		return;
    4.16 -
    4.17 -	targ = current->domain->vcpu[cpu];
    4.18 +	targ = d->vcpu[cpu];
    4.19  	if (targ == NULL)
    4.20  		return;
    4.21  
    4.22 -	if (vector == XEN_SAL_BOOT_RENDEZ_VEC
    4.23 -	    && !test_bit(_VCPUF_initialised, &targ->vcpu_flags)) {
    4.24 -		struct pt_regs *targ_regs = vcpu_regs (targ);
    4.25 -		struct vcpu_guest_context c;
    4.26 +  	if (vector == XEN_SAL_BOOT_RENDEZ_VEC
    4.27 +	    && (!test_bit(_VCPUF_initialised, &targ->vcpu_flags)
    4.28 +		|| test_bit(_VCPUF_down, &targ->vcpu_flags))) {
    4.29 +
    4.30 +		/* First start: initialize vpcu.  */
    4.31 +		if (!test_bit(_VCPUF_initialised, &targ->vcpu_flags)) {
    4.32 +			struct vcpu_guest_context c;
    4.33  		
    4.34 -		printf ("arch_boot_vcpu: %p %p\n",
    4.35 -			(void *)targ_regs->cr_iip,
    4.36 -			(void *)targ_regs->r1);
    4.37 -		memset (&c, 0, sizeof (c));
    4.38 -		/* Copy regs.  */
    4.39 -		c.regs.cr_iip = targ_regs->cr_iip;
    4.40 -		c.regs.r1 = targ_regs->r1;
    4.41 -		
    4.42 -		if (arch_set_info_guest (targ, &c) != 0) {
    4.43 -			printf ("arch_boot_vcpu: failure\n");
    4.44 -			return;
    4.45 +			memset (&c, 0, sizeof (c));
    4.46 +
    4.47 +			if (arch_set_info_guest (targ, &c) != 0) {
    4.48 +				printf ("arch_boot_vcpu: failure\n");
    4.49 +				return;
    4.50 +			}
    4.51  		}
    4.52 +			
    4.53 +		/* First or next rendez-vous: set registers.  */
    4.54 +		vcpu_init_regs (targ);
    4.55 +		vcpu_regs (targ)->cr_iip = d->arch.boot_rdv_ip;
    4.56 +		vcpu_regs (targ)->r1 = d->arch.boot_rdv_r1;
    4.57 +		vcpu_regs (targ)->b0 = d->arch.sal_return_addr;
    4.58 +
    4.59  		if (test_and_clear_bit(_VCPUF_down,
    4.60  				       &targ->vcpu_flags)) {
    4.61  			vcpu_wake(targ);
    4.62 -			printf ("arch_boot_vcpu: vcpu %d awaken %016lx!\n",
    4.63 -				targ->vcpu_id, targ_regs->cr_iip);
    4.64 +			printf ("arch_boot_vcpu: vcpu %d awaken\n",
    4.65 +				targ->vcpu_id);
    4.66  		}
    4.67  		else
    4.68  			printf ("arch_boot_vcpu: huu, already awaken!\n");
    4.69 @@ -253,6 +255,10 @@ fw_hypercall (struct pt_regs *regs)
    4.70  		regs->r8 = x.r8; regs->r9 = x.r9;
    4.71  		regs->r10 = x.r10; regs->r11 = x.r11;
    4.72  		break;
    4.73 + 	    case FW_HYPERCALL_SAL_RETURN:
    4.74 +	        if ( !test_and_set_bit(_VCPUF_down, &v->vcpu_flags) )
    4.75 +			vcpu_sleep_nosync(v);
    4.76 +		break;
    4.77  	    case FW_HYPERCALL_EFI_CALL:
    4.78  		efi_ret_value = efi_emulator (regs, &fault);
    4.79  		if (fault != IA64_NO_FAULT) return fault;
     5.1 --- a/xen/arch/ia64/xen/privop.c	Sat Jun 03 14:42:13 2006 -0600
     5.2 +++ b/xen/arch/ia64/xen/privop.c	Sat Jun 03 14:48:42 2006 -0600
     5.3 @@ -166,19 +166,19 @@ IA64FAULT priv_ptc_ga(VCPU *vcpu, INST64
     5.4  IA64FAULT priv_ptr_d(VCPU *vcpu, INST64 inst)
     5.5  {
     5.6  	UINT64 vadr = vcpu_get_gr(vcpu,inst.M45.r3);
     5.7 -	UINT64 addr_range;
     5.8 +	UINT64 log_range;
     5.9  
    5.10 -	addr_range = 1 << ((vcpu_get_gr(vcpu,inst.M45.r2) & 0xfc) >> 2);
    5.11 -	return vcpu_ptr_d(vcpu,vadr,addr_range);
    5.12 +	log_range = (vcpu_get_gr(vcpu,inst.M45.r2) & 0xfc) >> 2;
    5.13 +	return vcpu_ptr_d(vcpu,vadr,log_range);
    5.14  }
    5.15  
    5.16  IA64FAULT priv_ptr_i(VCPU *vcpu, INST64 inst)
    5.17  {
    5.18  	UINT64 vadr = vcpu_get_gr(vcpu,inst.M45.r3);
    5.19 -	UINT64 addr_range;
    5.20 +	UINT64 log_range;
    5.21  
    5.22 -	addr_range = 1 << ((vcpu_get_gr(vcpu,inst.M45.r2) & 0xfc) >> 2);
    5.23 -	return vcpu_ptr_i(vcpu,vadr,addr_range);
    5.24 +	log_range = (vcpu_get_gr(vcpu,inst.M45.r2) & 0xfc) >> 2;
    5.25 +	return vcpu_ptr_i(vcpu,vadr,log_range);
    5.26  }
    5.27  
    5.28  IA64FAULT priv_tpa(VCPU *vcpu, INST64 inst)
     6.1 --- a/xen/arch/ia64/xen/vcpu.c	Sat Jun 03 14:42:13 2006 -0600
     6.2 +++ b/xen/arch/ia64/xen/vcpu.c	Sat Jun 03 14:48:42 2006 -0600
     6.3 @@ -143,6 +143,45 @@ vcpu_set_gr(VCPU *vcpu, unsigned long re
     6.4  }
     6.5  
     6.6  #endif
     6.7 +
     6.8 +void vcpu_init_regs (struct vcpu *v)
     6.9 +{
    6.10 +	struct pt_regs *regs;
    6.11 +
    6.12 +	regs = vcpu_regs (v);
    6.13 +	if (VMX_DOMAIN(v)) {
    6.14 +		/* dt/rt/it:1;i/ic:1, si:1, vm/bn:1, ac:1 */
    6.15 +		/* Need to be expanded as macro */
    6.16 +		regs->cr_ipsr = 0x501008826008;
    6.17 +	} else {
    6.18 +		regs->cr_ipsr = ia64_getreg(_IA64_REG_PSR)
    6.19 +		  | IA64_PSR_BITS_TO_SET | IA64_PSR_BN;
    6.20 +		regs->cr_ipsr &= ~(IA64_PSR_BITS_TO_CLEAR
    6.21 +				   | IA64_PSR_RI | IA64_PSR_IS);
    6.22 +		// domain runs at PL2
    6.23 +		regs->cr_ipsr |= 2UL << IA64_PSR_CPL0_BIT;
    6.24 +	}
    6.25 +	regs->cr_ifs = 1UL << 63; /* or clear? */
    6.26 +	regs->ar_fpsr = FPSR_DEFAULT;
    6.27 +
    6.28 +	if (VMX_DOMAIN(v)) {
    6.29 +		vmx_init_all_rr(v);
    6.30 +		/* Virtual processor context setup */
    6.31 +		VCPU(v, vpsr) = IA64_PSR_BN;
    6.32 +		VCPU(v, dcr) = 0;
    6.33 +	} else {
    6.34 +		init_all_rr(v);
    6.35 +		regs->ar_rsc |= (2 << 2); /* force PL2/3 */
    6.36 +		VCPU(v, banknum) = 1;
    6.37 +		VCPU(v, metaphysical_mode) = 1;
    6.38 +		VCPU(v, interrupt_mask_addr) =
    6.39 +		    (uint64_t)SHAREDINFO_ADDR + INT_ENABLE_OFFSET(v);
    6.40 +		VCPU(v, itv) = (1 << 16); /* timer vector masked */
    6.41 +	}
    6.42 +
    6.43 +	v->arch.domain_itm_last = -1L;
    6.44 +}
    6.45 +
    6.46  /**************************************************************************
    6.47   VCPU privileged application register access routines
    6.48  **************************************************************************/
    6.49 @@ -1303,6 +1342,12 @@ unsigned long recover_to_break_fault_cou
    6.50  
    6.51  int warn_region0_address = 0; // FIXME later: tie to a boot parameter?
    6.52  
    6.53 +/* Return TRUE iff [b1,e1] and [b2,e2] partially or fully overlaps.  */
    6.54 +static inline int range_overlap (u64 b1, u64 e1, u64 b2, u64 e2)
    6.55 +{
    6.56 +	return (b1 <= e2) && (e1 >= b2);
    6.57 +}
    6.58 +
    6.59  // FIXME: also need to check && (!trp->key || vcpu_pkr_match(trp->key))
    6.60  static inline int vcpu_match_tr_entry_no_p(TR_ENTRY *trp, UINT64 ifa, UINT64 rid)
    6.61  {
    6.62 @@ -1316,6 +1361,16 @@ static inline int vcpu_match_tr_entry(TR
    6.63  	return trp->pte.p && vcpu_match_tr_entry_no_p(trp, ifa, rid);
    6.64  }
    6.65  
    6.66 +static inline int
    6.67 +vcpu_match_tr_entry_range(TR_ENTRY *trp, UINT64 rid, u64 b, u64 e)
    6.68 +{
    6.69 +	return trp->rid == rid
    6.70 +		&& trp->pte.p
    6.71 +		&& range_overlap (b, e,
    6.72 +				  trp->vadr, trp->vadr + (1L << trp->ps) - 1);
    6.73 +
    6.74 +}
    6.75 +
    6.76  static TR_ENTRY*
    6.77  vcpu_tr_lookup(VCPU* vcpu, unsigned long va, UINT64 rid, BOOLEAN is_data)
    6.78  {
    6.79 @@ -1443,8 +1498,8 @@ IA64FAULT vcpu_translate(VCPU *vcpu, UIN
    6.80  			 * region=5,VMM need to handle this tlb miss as if
    6.81  			 * PSCB(vcpu,metaphysical_mode)=0
    6.82  			 */           
    6.83 -			printk("vcpu_translate: bad physical address: 0x%lx\n",
    6.84 -			       address);
    6.85 +			printk("vcpu_translate: bad physical address: 0x%lx at %lx\n",
    6.86 +			       address, vcpu_regs (vcpu)->cr_iip);
    6.87  
    6.88  		} else {
    6.89  			*pteval = (address & _PAGE_PPN_MASK) | __DIRTY_BITS |
    6.90 @@ -1877,8 +1932,6 @@ IA64FAULT vcpu_itr_i(VCPU *vcpu, UINT64 
    6.91   VCPU translation cache access routines
    6.92  **************************************************************************/
    6.93  
    6.94 -void foobar(void) { /*vcpu_verbose = 1;*/ }
    6.95 -
    6.96  void vcpu_itc_no_srlz(VCPU *vcpu, UINT64 IorD, UINT64 vaddr, UINT64 pte, UINT64 mp_pte, UINT64 logps)
    6.97  {
    6.98  	unsigned long psr;
    6.99 @@ -1967,11 +2020,12 @@ IA64FAULT vcpu_ptc_l(VCPU *vcpu, UINT64 
   6.100  	vcpu_purge_tr_entry(&PSCBX(vcpu,dtlb));
   6.101  	vcpu_purge_tr_entry(&PSCBX(vcpu,itlb));
   6.102  	
   6.103 -	/*Purge all tlb and vhpt*/
   6.104 +	/* Purge all tlb and vhpt */
   6.105  	vcpu_flush_tlb_vhpt_range (vadr, log_range);
   6.106  
   6.107  	return IA64_NO_FAULT;
   6.108  }
   6.109 +
   6.110  // At privlvl=0, fc performs no access rights or protection key checks, while
   6.111  // at privlvl!=0, fc performs access rights checks as if it were a 1-byte
   6.112  // read but no protection key check.  Thus in order to avoid an unexpected
   6.113 @@ -2021,16 +2075,59 @@ IA64FAULT vcpu_ptc_ga(VCPU *vcpu,UINT64 
   6.114  	return IA64_NO_FAULT;
   6.115  }
   6.116  
   6.117 -IA64FAULT vcpu_ptr_d(VCPU *vcpu,UINT64 vadr,UINT64 addr_range)
   6.118 +IA64FAULT vcpu_ptr_d(VCPU *vcpu,UINT64 vadr,UINT64 log_range)
   6.119  {
   6.120 -	printf("vcpu_ptr_d: Purging TLB is unsupported\n");
   6.121 -	// don't forget to recompute dtr_regions
   6.122 -	return (IA64_ILLOP_FAULT);
   6.123 +	unsigned long region = vadr >> 61;
   6.124 +	u64 addr_range = 1UL << log_range;
   6.125 +	unsigned long rid, rr;
   6.126 +	int i;
   6.127 +	TR_ENTRY *trp;
   6.128 +
   6.129 +	rr = PSCB(vcpu,rrs)[region];
   6.130 +	rid = rr & RR_RID_MASK;
   6.131 +
   6.132 +	/* Purge TC  */
   6.133 +	vcpu_purge_tr_entry(&PSCBX(vcpu,dtlb));
   6.134 +
   6.135 +	/* Purge tr and recompute dtr_regions.  */
   6.136 +	vcpu->arch.dtr_regions = 0;
   6.137 +	for (trp = vcpu->arch.dtrs, i = NDTRS; i; i--, trp++)
   6.138 +		if (vcpu_match_tr_entry_range (trp,rid, vadr, vadr+addr_range))
   6.139 +			vcpu_purge_tr_entry(trp);
   6.140 +		else if (trp->pte.p)
   6.141 +			vcpu_quick_region_set(vcpu->arch.dtr_regions,
   6.142 +					      trp->vadr);
   6.143 +
   6.144 +	vcpu_flush_tlb_vhpt_range (vadr, log_range);
   6.145 +
   6.146 +	return IA64_NO_FAULT;
   6.147  }
   6.148  
   6.149 -IA64FAULT vcpu_ptr_i(VCPU *vcpu,UINT64 vadr,UINT64 addr_range)
   6.150 +IA64FAULT vcpu_ptr_i(VCPU *vcpu,UINT64 vadr,UINT64 log_range)
   6.151  {
   6.152 -	printf("vcpu_ptr_i: Purging TLB is unsupported\n");
   6.153 -	// don't forget to recompute itr_regions
   6.154 -	return (IA64_ILLOP_FAULT);
   6.155 +	unsigned long region = vadr >> 61;
   6.156 +	u64 addr_range = 1UL << log_range;
   6.157 +	unsigned long rid, rr;
   6.158 +	int i;
   6.159 +	TR_ENTRY *trp;
   6.160 +
   6.161 +	rr = PSCB(vcpu,rrs)[region];
   6.162 +	rid = rr & RR_RID_MASK;
   6.163 +
   6.164 +	/* Purge TC  */
   6.165 +	vcpu_purge_tr_entry(&PSCBX(vcpu,itlb));
   6.166 +
   6.167 +	/* Purge tr and recompute itr_regions.  */
   6.168 +	vcpu->arch.itr_regions = 0;
   6.169 +	for (trp = vcpu->arch.itrs, i = NITRS; i; i--, trp++)
   6.170 +		if (vcpu_match_tr_entry_range (trp,rid, vadr, vadr+addr_range))
   6.171 +			vcpu_purge_tr_entry(trp);
   6.172 +		else if (trp->pte.p)
   6.173 +			vcpu_quick_region_set(vcpu->arch.itr_regions,
   6.174 +					      trp->vadr);
   6.175 +
   6.176 +
   6.177 +	vcpu_flush_tlb_vhpt_range (vadr, log_range);
   6.178 +
   6.179 +	return IA64_NO_FAULT;
   6.180  }
     7.1 --- a/xen/include/asm-ia64/dom_fw.h	Sat Jun 03 14:42:13 2006 -0600
     7.2 +++ b/xen/include/asm-ia64/dom_fw.h	Sat Jun 03 14:48:42 2006 -0600
     7.3 @@ -21,6 +21,11 @@
     7.4  #define	FW_HYPERCALL_END_PADDR HYPERCALL_END
     7.5  #define	FW_HYPERCALL_PADDR(index) (FW_HYPERCALL_BASE_PADDR + (16UL * index))
     7.6  
     7.7 +/* Hypercalls number have a low part and a high part.
     7.8 +   The high part is the class (xen/pal/sal/efi).  */
     7.9 +#define FW_HYPERCALL_NUM_MASK_HIGH	~0xffUL
    7.10 +#define FW_HYPERCALL_NUM_MASK_LOW	 0xffUL
    7.11 +
    7.12  /*
    7.13   * PAL can be called in physical or virtual mode simply by
    7.14   * branching to pal_entry_point, which is found in one of the
    7.15 @@ -57,6 +62,11 @@
    7.16  #define FW_HYPERCALL_SAL_CALL_PADDR	FW_HYPERCALL_PADDR(FW_HYPERCALL_SAL_CALL_INDEX)
    7.17  #define FW_HYPERCALL_SAL_CALL		0x1100UL
    7.18  
    7.19 +/* SAL return point.  */
    7.20 +#define FW_HYPERCALL_SAL_RETURN_INDEX	0x84UL
    7.21 +#define FW_HYPERCALL_SAL_RETURN_PADDR	FW_HYPERCALL_PADDR(FW_HYPERCALL_SAL_RETURN_INDEX)
    7.22 +#define FW_HYPERCALL_SAL_RETURN		0x1200UL
    7.23 +
    7.24  /*
    7.25   * EFI is accessed via the EFI system table, which contains:
    7.26   * - a header which contains version info
    7.27 @@ -81,7 +91,6 @@
    7.28   */
    7.29  
    7.30  /* these are indexes into the runtime services table */
    7.31 -#define	FW_HYPERCALL_EFI_BASE
    7.32  #define FW_HYPERCALL_EFI_GET_TIME_INDEX			0UL
    7.33  #define FW_HYPERCALL_EFI_SET_TIME_INDEX			1UL
    7.34  #define FW_HYPERCALL_EFI_GET_WAKEUP_TIME_INDEX		2UL
    7.35 @@ -130,8 +139,8 @@
    7.36   * This is a hypercall number for FPSWA.
    7.37   * FPSWA hypercall uses 2 bundles for a pseudo-entry-point and a hypercall-patch.
    7.38   */
    7.39 -#define FW_HYPERCALL_FPSWA_ENTRY_INDEX			0x83UL
    7.40 -#define FW_HYPERCALL_FPSWA_PATCH_INDEX			0x84UL
    7.41 +#define FW_HYPERCALL_FPSWA_ENTRY_INDEX			0x90UL
    7.42 +#define FW_HYPERCALL_FPSWA_PATCH_INDEX			0x91UL
    7.43  #define FW_HYPERCALL_FPSWA_ENTRY_PADDR			FW_HYPERCALL_PADDR(FW_HYPERCALL_FPSWA_ENTRY_INDEX)
    7.44  #define FW_HYPERCALL_FPSWA_PATCH_PADDR			FW_HYPERCALL_PADDR(FW_HYPERCALL_FPSWA_PATCH_INDEX)
    7.45  #define FW_HYPERCALL_FPSWA				0x500UL
    7.46 @@ -149,9 +158,6 @@
    7.47  /* Interrupt vector used for os boot rendez vous.  */
    7.48  #define XEN_SAL_BOOT_RENDEZ_VEC	0xF3
    7.49  
    7.50 -#define FW_HYPERCALL_NUM_MASK_HIGH	~0xffUL
    7.51 -#define FW_HYPERCALL_NUM_MASK_LOW	 0xffUL
    7.52 -
    7.53  #define EFI_MEMDESC_VERSION		1
    7.54  
    7.55  extern struct ia64_pal_retval xen_pal_emulator(UINT64, u64, u64, u64);
     8.1 --- a/xen/include/asm-ia64/domain.h	Sat Jun 03 14:42:13 2006 -0600
     8.2 +++ b/xen/include/asm-ia64/domain.h	Sat Jun 03 14:48:42 2006 -0600
     8.3 @@ -54,6 +54,13 @@ struct arch_domain {
     8.4      struct virtual_platform_def     vmx_platform;
     8.5  #define	hvm_domain vmx_platform /* platform defs are not vmx specific */
     8.6  
     8.7 +    /* OS boot rendez vous.  */
     8.8 +    unsigned long boot_rdv_ip;
     8.9 +    unsigned long boot_rdv_r1;
    8.10 +
    8.11 +    /* SAL return point.  */
    8.12 +    unsigned long sal_return_addr;
    8.13 +
    8.14      u64 xen_vastart;
    8.15      u64 xen_vaend;
    8.16      u64 shared_info_va;
     9.1 --- a/xen/include/asm-ia64/vcpu.h	Sat Jun 03 14:42:13 2006 -0600
     9.2 +++ b/xen/include/asm-ia64/vcpu.h	Sat Jun 03 14:48:42 2006 -0600
     9.3 @@ -149,8 +149,8 @@ extern IA64FAULT vcpu_ptc_l(VCPU *vcpu, 
     9.4  extern IA64FAULT vcpu_ptc_e(VCPU *vcpu, UINT64 vadr);
     9.5  extern IA64FAULT vcpu_ptc_g(VCPU *vcpu, UINT64 vadr, UINT64 addr_range);
     9.6  extern IA64FAULT vcpu_ptc_ga(VCPU *vcpu, UINT64 vadr, UINT64 addr_range);
     9.7 -extern IA64FAULT vcpu_ptr_d(VCPU *vcpu,UINT64 vadr, UINT64 addr_range);
     9.8 -extern IA64FAULT vcpu_ptr_i(VCPU *vcpu,UINT64 vadr, UINT64 addr_range);
     9.9 +extern IA64FAULT vcpu_ptr_d(VCPU *vcpu,UINT64 vadr, UINT64 log_range);
    9.10 +extern IA64FAULT vcpu_ptr_i(VCPU *vcpu,UINT64 vadr, UINT64 log_range);
    9.11  union U_IA64_BUNDLE;
    9.12  extern int vcpu_get_domain_bundle(VCPU *vcpu, REGS *regs, UINT64 gip, union U_IA64_BUNDLE *bundle);
    9.13  extern IA64FAULT vcpu_translate(VCPU *vcpu, UINT64 address, BOOLEAN is_data,
    9.14 @@ -176,6 +176,9 @@ extern void vcpu_itc_no_srlz(VCPU *vcpu,
    9.15  extern UINT64 vcpu_get_tmp(VCPU *, UINT64);
    9.16  extern void vcpu_set_tmp(VCPU *, UINT64, UINT64);
    9.17  
    9.18 +/* Initialize vcpu regs.  */
    9.19 +extern void vcpu_init_regs (struct vcpu *v);
    9.20 +
    9.21  static inline UINT64
    9.22  itir_ps(UINT64 itir)
    9.23  {