ia64/xen-unstable

changeset 9752:de0c04ed4ab7

[IA64] SMP-guest

Final SMP-guest patch: add IPI and boot rendez-vous support.

Signed-off-by: Tristan Gingold <tristan.gingold@bull.net>
author awilliam@xenbuild.aw
date Fri Apr 21 10:40:17 2006 -0600 (2006-04-21)
parents bbf325d76768
children 3575cd80ba8c
files linux-2.6-xen-sparse/arch/ia64/kernel/irq_ia64.c linux-2.6-xen-sparse/arch/ia64/xen/hypercall.S xen/arch/ia64/xen/dom_fw.c xen/arch/ia64/xen/hypercall.c xen/include/asm-ia64/dom_fw.h
line diff
     1.1 --- a/linux-2.6-xen-sparse/arch/ia64/kernel/irq_ia64.c	Fri Apr 21 09:20:13 2006 -0600
     1.2 +++ b/linux-2.6-xen-sparse/arch/ia64/kernel/irq_ia64.c	Fri Apr 21 10:40:17 2006 -0600
     1.3 @@ -265,6 +265,14 @@ ia64_send_ipi (int cpu, int vector, int 
     1.4  	unsigned long ipi_data;
     1.5  	unsigned long phys_cpu_id;
     1.6  
     1.7 +#ifdef CONFIG_XEN
     1.8 +        if (running_on_xen) {
     1.9 +                extern void xen_send_ipi (int cpu, int vec);
    1.10 +                xen_send_ipi (cpu, vector);
    1.11 +                return;
    1.12 +        }
    1.13 +#endif /* CONFIG_XEN */
    1.14 +
    1.15  #ifdef CONFIG_SMP
    1.16  	phys_cpu_id = cpu_physical_id(cpu);
    1.17  #else
     2.1 --- a/linux-2.6-xen-sparse/arch/ia64/xen/hypercall.S	Fri Apr 21 09:20:13 2006 -0600
     2.2 +++ b/linux-2.6-xen-sparse/arch/ia64/xen/hypercall.S	Fri Apr 21 10:40:17 2006 -0600
     2.3 @@ -341,3 +341,13 @@ GLOBAL_ENTRY(xen_set_eflag)
     2.4  	br.ret.sptk.many rp
     2.5  END(xen_set_eflag)
     2.6  #endif
     2.7 +
     2.8 +GLOBAL_ENTRY(xen_send_ipi)
     2.9 +        mov r14=r32
    2.10 +        mov r15=r33
    2.11 +        mov r2=0x380
    2.12 +        break 0x1000
    2.13 +        ;;
    2.14 +        br.ret.sptk.many rp
    2.15 +        ;;
    2.16 +END(xen_send_ipi)
     3.1 --- a/xen/arch/ia64/xen/dom_fw.c	Fri Apr 21 09:20:13 2006 -0600
     3.2 +++ b/xen/arch/ia64/xen/dom_fw.c	Fri Apr 21 10:40:17 2006 -0600
     3.3 @@ -94,9 +94,24 @@ unsigned long dom_fw_setup(struct domain
     3.4  
     3.5  /* the following heavily leveraged from linux/arch/ia64/hp/sim/fw-emu.c */
     3.6  
     3.7 -#define NUM_EFI_SYS_TABLES 6
     3.8 -# define NUM_MEM_DESCS	5
     3.9 +/* Set IP and GR1 of not yet initialized vcpu.  */
    3.10 +static void
    3.11 +set_os_boot_rendez (struct domain *d, unsigned long pc, unsigned long gr1)
    3.12 +{
    3.13 +	struct vcpu *v;
    3.14 +	int i;
    3.15  
    3.16 +	printf ("set_os_boot_rendez: %lx %lx\n", pc, gr1);
    3.17 +	for (i = 1; i < MAX_VIRT_CPUS; i++) {
    3.18 +		v = d->vcpu[i];
    3.19 +		if (v != NULL
    3.20 +		    && !test_bit(_VCPUF_initialised, &v->vcpu_flags)) {
    3.21 +			struct pt_regs *regs = vcpu_regs (v);
    3.22 +			regs->cr_iip = pc;
    3.23 +			regs->r1 = gr1;
    3.24 +		}
    3.25 +	}
    3.26 +}
    3.27  
    3.28  struct sal_ret_values
    3.29  sal_emulator (long index, unsigned long in1, unsigned long in2,
    3.30 @@ -155,7 +170,18 @@ sal_emulator (long index, unsigned long 
    3.31  		     printf("NON-PRIV DOMAIN CALLED SAL_PCI_CONFIG_WRITE\n");
    3.32  		break;
    3.33  	    case SAL_SET_VECTORS:
    3.34 -		printf("*** CALLED SAL_SET_VECTORS.  IGNORED...\n");
    3.35 + 		if (in1 == SAL_VECTOR_OS_BOOT_RENDEZ) {
    3.36 + 			if (in4 != 0 || in5 != 0 || in6 != 0 || in7 != 0) {
    3.37 + 				/* Sanity check: cs_length1 must be 0,
    3.38 + 				   second vector is reserved.  */
    3.39 + 				status = -2;
    3.40 + 			}
    3.41 + 			else
    3.42 + 				set_os_boot_rendez (current->domain, in2, in3);
    3.43 + 		}
    3.44 + 		else
    3.45 + 			printf("*** CALLED SAL_SET_VECTORS %lu.  IGNORED...\n",
    3.46 + 			       in1);
    3.47  		break;
    3.48  	    case SAL_GET_STATE_INFO:
    3.49  		/* No more info.  */
    3.50 @@ -618,6 +644,9 @@ dom_fw_fake_acpi(struct domain *d, struc
    3.51  	return;
    3.52  }
    3.53  
    3.54 +#define NUM_EFI_SYS_TABLES 6
    3.55 +#define NUM_MEM_DESCS	5
    3.56 +
    3.57  static struct ia64_boot_param *
    3.58  dom_fw_init (struct domain *d, const char *args, int arglen, char *fw_mem, int fw_mem_size)
    3.59  {
    3.60 @@ -625,8 +654,9 @@ dom_fw_init (struct domain *d, const cha
    3.61  	efi_runtime_services_t *efi_runtime;
    3.62  	efi_config_table_t *efi_tables;
    3.63  	struct ia64_sal_systab *sal_systab;
    3.64 +	struct ia64_sal_desc_entry_point *sal_ed;
    3.65 +	struct ia64_sal_desc_ap_wakeup *sal_wakeup;
    3.66  	efi_memory_desc_t *efi_memmap, *md;
    3.67 -	struct ia64_sal_desc_entry_point *sal_ed;
    3.68  	struct ia64_boot_param *bp;
    3.69  	unsigned long *pfn;
    3.70  	unsigned char checksum = 0;
    3.71 @@ -662,6 +692,7 @@ dom_fw_init (struct domain *d, const cha
    3.72  	efi_tables  = (void *) cp; cp += NUM_EFI_SYS_TABLES * sizeof(*efi_tables);
    3.73  	sal_systab  = (void *) cp; cp += sizeof(*sal_systab);
    3.74  	sal_ed      = (void *) cp; cp += sizeof(*sal_ed);
    3.75 +	sal_wakeup  = (void *) cp; cp += sizeof(*sal_wakeup);
    3.76  	efi_memmap  = (void *) cp; cp += NUM_MEM_DESCS*sizeof(*efi_memmap);
    3.77  	bp	    = (void *) cp; cp += sizeof(*bp);
    3.78  	pfn         = (void *) cp; cp += NFUNCPTRS * 2 * sizeof(pfn);
    3.79 @@ -779,7 +810,7 @@ dom_fw_init (struct domain *d, const cha
    3.80  	sal_systab->size = sizeof(*sal_systab);
    3.81  	sal_systab->sal_rev_minor = 1;
    3.82  	sal_systab->sal_rev_major = 0;
    3.83 -	sal_systab->entry_count = 1;
    3.84 +	sal_systab->entry_count = 2;
    3.85  
    3.86  	strcpy((char *)sal_systab->oem_id, "Xen/ia64");
    3.87  	strcpy((char *)sal_systab->product_id, "Xen/ia64");
    3.88 @@ -792,6 +823,11 @@ dom_fw_init (struct domain *d, const cha
    3.89  	dom_fw_hypercall_patch (d, sal_ed->sal_proc, FW_HYPERCALL_SAL_CALL, 1);
    3.90  	sal_ed->gp = 0;  // will be ignored
    3.91  
    3.92 +	/* Fill an AP wakeup descriptor.  */
    3.93 +	sal_wakeup->type = SAL_DESC_AP_WAKEUP;
    3.94 +	sal_wakeup->mechanism = IA64_SAL_AP_EXTERNAL_INT;
    3.95 +	sal_wakeup->vector = XEN_SAL_BOOT_RENDEZ_VEC;
    3.96 +
    3.97  	for (cp = (char *) sal_systab; cp < (char *) efi_memmap; ++cp)
    3.98  		checksum += *cp;
    3.99  
     4.1 --- a/xen/arch/ia64/xen/hypercall.c	Fri Apr 21 09:20:13 2006 -0600
     4.2 +++ b/xen/arch/ia64/xen/hypercall.c	Fri Apr 21 10:40:17 2006 -0600
     4.3 @@ -132,6 +132,65 @@ xen_hypercall (struct pt_regs *regs)
     4.4  }
     4.5  
     4.6  
     4.7 +static void
     4.8 +fw_hypercall_ipi (struct pt_regs *regs)
     4.9 +{
    4.10 +	int cpu = regs->r14;
    4.11 +	int vector = regs->r15;
    4.12 +	struct vcpu *targ;
    4.13 +		    
    4.14 +	if (0 && vector == 254)
    4.15 +		printf ("send_ipi from %d to %d vector=%d\n",
    4.16 +			current->vcpu_id, cpu, vector);
    4.17 +
    4.18 +	if (cpu > MAX_VIRT_CPUS)
    4.19 +		return;
    4.20 +
    4.21 +	targ = current->domain->vcpu[cpu];
    4.22 +	if (targ == NULL)
    4.23 +		return;
    4.24 +
    4.25 +	if (vector == XEN_SAL_BOOT_RENDEZ_VEC
    4.26 +	    && !test_bit(_VCPUF_initialised, &targ->vcpu_flags)) {
    4.27 +		struct pt_regs *targ_regs = vcpu_regs (targ);
    4.28 +		struct vcpu_guest_context c;
    4.29 +		
    4.30 +		printf ("arch_boot_vcpu: %p %p\n",
    4.31 +			(void *)targ_regs->cr_iip,
    4.32 +			(void *)targ_regs->r1);
    4.33 +		memset (&c, 0, sizeof (c));
    4.34 +		/* Copy regs.  */
    4.35 +		c.regs.cr_iip = targ_regs->cr_iip;
    4.36 +		c.regs.r1 = targ_regs->r1;
    4.37 +		
    4.38 +		/* Copy from vcpu 0.  */
    4.39 +		c.vcpu.evtchn_vector =
    4.40 +			current->domain->vcpu[0]->vcpu_info->arch.evtchn_vector;
    4.41 +		if (arch_set_info_guest (targ, &c) != 0) {
    4.42 +			printf ("arch_boot_vcpu: failure\n");
    4.43 +			return;
    4.44 +		}
    4.45 +		if (test_and_clear_bit(_VCPUF_down,
    4.46 +				       &targ->vcpu_flags)) {
    4.47 +			vcpu_wake(targ);
    4.48 +			printf ("arch_boot_vcpu: vcpu %d awaken %016lx!\n",
    4.49 +				targ->vcpu_id, targ_regs->cr_iip);
    4.50 +		}
    4.51 +		else
    4.52 +			printf ("arch_boot_vcpu: huu, already awaken!");
    4.53 +	}
    4.54 +	else {
    4.55 +		int running = test_bit(_VCPUF_running,
    4.56 +				       &targ->vcpu_flags);
    4.57 +		
    4.58 +		vcpu_pend_interrupt(targ, vector);
    4.59 +		vcpu_unblock(targ);
    4.60 +		if (running)
    4.61 +			smp_send_event_check_cpu(targ->processor);
    4.62 +	}
    4.63 +	return;
    4.64 +}
    4.65 +
    4.66  static int
    4.67  fw_hypercall (struct pt_regs *regs)
    4.68  {
    4.69 @@ -232,6 +291,9 @@ fw_hypercall (struct pt_regs *regs)
    4.70  		// FIXME: need fixes in efi.h from 2.6.9
    4.71  		regs->r8 = EFI_UNSUPPORTED;
    4.72  		break;
    4.73 +	    case FW_HYPERCALL_IPI:
    4.74 +		fw_hypercall_ipi (regs);
    4.75 +		break;
    4.76  	    default:
    4.77  		printf("unknown ia64 fw hypercall %lx\n", regs->r2);
    4.78  		regs->r8 = do_ni_hypercall();
     5.1 --- a/xen/include/asm-ia64/dom_fw.h	Fri Apr 21 09:20:13 2006 -0600
     5.2 +++ b/xen/include/asm-ia64/dom_fw.h	Fri Apr 21 10:40:17 2006 -0600
     5.3 @@ -125,9 +125,14 @@ extern unsigned long dom_fw_setup(struct
     5.4  */
     5.5  #define FW_HYPERCALL_FIRST_ARCH		0x300UL
     5.6  
     5.7 +#define FW_HYPERCALL_IPI		0x380UL
     5.8 +
     5.9  /* Xen/ia64 user hypercalls.  Only used for debugging.  */
    5.10  #define FW_HYPERCALL_FIRST_USER		0xff00UL
    5.11  
    5.12 +/* Interrupt vector used for os boot rendez vous.  */
    5.13 +#define XEN_SAL_BOOT_RENDEZ_VEC	0xF3
    5.14 +
    5.15  extern struct ia64_pal_retval xen_pal_emulator(UINT64, u64, u64, u64);
    5.16  extern struct sal_ret_values sal_emulator (long index, unsigned long in1, unsigned long in2, unsigned long in3, unsigned long in4, unsigned long in5, unsigned long in6, unsigned long in7);
    5.17  extern struct ia64_pal_retval pal_emulator_static (unsigned long);