diff options
-rw-r--r-- | arch/x86/include/asm/xen/hypercall.h | 118 | ||||
-rw-r--r-- | arch/x86/mm/init.c | 17 | ||||
-rw-r--r-- | arch/x86/xen/enlighten_pv.c | 13 | ||||
-rw-r--r-- | arch/x86/xen/mmu_pv.c | 2 | ||||
-rw-r--r-- | arch/x86/xen/setup.c | 31 | ||||
-rw-r--r-- | arch/x86/xen/xen-ops.h | 1 | ||||
-rw-r--r-- | drivers/acpi/processor_core.c | 1 | ||||
-rw-r--r-- | drivers/xen/mcelog.c | 2 | ||||
-rw-r--r-- | drivers/xen/xen-acpi-processor.c | 6 |
9 files changed, 30 insertions, 161 deletions
diff --git a/arch/x86/include/asm/xen/hypercall.h b/arch/x86/include/asm/xen/hypercall.h index 6b2f90a0b149..ef05bea7010d 100644 --- a/arch/x86/include/asm/xen/hypercall.h +++ b/arch/x86/include/asm/xen/hypercall.h | |||
@@ -197,17 +197,6 @@ extern struct { char _entry[32]; } hypercall_page[]; | |||
197 | (type)__res; \ | 197 | (type)__res; \ |
198 | }) | 198 | }) |
199 | 199 | ||
200 | #define _hypercall5(type, name, a1, a2, a3, a4, a5) \ | ||
201 | ({ \ | ||
202 | __HYPERCALL_DECLS; \ | ||
203 | __HYPERCALL_5ARG(a1, a2, a3, a4, a5); \ | ||
204 | asm volatile (__HYPERCALL \ | ||
205 | : __HYPERCALL_5PARAM \ | ||
206 | : __HYPERCALL_ENTRY(name) \ | ||
207 | : __HYPERCALL_CLOBBER5); \ | ||
208 | (type)__res; \ | ||
209 | }) | ||
210 | |||
211 | static inline long | 200 | static inline long |
212 | xen_single_call(unsigned int call, | 201 | xen_single_call(unsigned int call, |
213 | unsigned long a1, unsigned long a2, | 202 | unsigned long a1, unsigned long a2, |
@@ -267,47 +256,12 @@ HYPERVISOR_set_gdt(unsigned long *frame_list, int entries) | |||
267 | } | 256 | } |
268 | 257 | ||
269 | static inline int | 258 | static inline int |
270 | HYPERVISOR_stack_switch(unsigned long ss, unsigned long esp) | ||
271 | { | ||
272 | return _hypercall2(int, stack_switch, ss, esp); | ||
273 | } | ||
274 | |||
275 | #ifdef CONFIG_X86_32 | ||
276 | static inline int | ||
277 | HYPERVISOR_set_callbacks(unsigned long event_selector, | ||
278 | unsigned long event_address, | ||
279 | unsigned long failsafe_selector, | ||
280 | unsigned long failsafe_address) | ||
281 | { | ||
282 | return _hypercall4(int, set_callbacks, | ||
283 | event_selector, event_address, | ||
284 | failsafe_selector, failsafe_address); | ||
285 | } | ||
286 | #else /* CONFIG_X86_64 */ | ||
287 | static inline int | ||
288 | HYPERVISOR_set_callbacks(unsigned long event_address, | ||
289 | unsigned long failsafe_address, | ||
290 | unsigned long syscall_address) | ||
291 | { | ||
292 | return _hypercall3(int, set_callbacks, | ||
293 | event_address, failsafe_address, | ||
294 | syscall_address); | ||
295 | } | ||
296 | #endif /* CONFIG_X86_{32,64} */ | ||
297 | |||
298 | static inline int | ||
299 | HYPERVISOR_callback_op(int cmd, void *arg) | 259 | HYPERVISOR_callback_op(int cmd, void *arg) |
300 | { | 260 | { |
301 | return _hypercall2(int, callback_op, cmd, arg); | 261 | return _hypercall2(int, callback_op, cmd, arg); |
302 | } | 262 | } |
303 | 263 | ||
304 | static inline int | 264 | static inline int |
305 | HYPERVISOR_fpu_taskswitch(int set) | ||
306 | { | ||
307 | return _hypercall1(int, fpu_taskswitch, set); | ||
308 | } | ||
309 | |||
310 | static inline int | ||
311 | HYPERVISOR_sched_op(int cmd, void *arg) | 265 | HYPERVISOR_sched_op(int cmd, void *arg) |
312 | { | 266 | { |
313 | return _hypercall2(int, sched_op, cmd, arg); | 267 | return _hypercall2(int, sched_op, cmd, arg); |
@@ -419,19 +373,6 @@ HYPERVISOR_grant_table_op(unsigned int cmd, void *uop, unsigned int count) | |||
419 | } | 373 | } |
420 | 374 | ||
421 | static inline int | 375 | static inline int |
422 | HYPERVISOR_update_va_mapping_otherdomain(unsigned long va, pte_t new_val, | ||
423 | unsigned long flags, domid_t domid) | ||
424 | { | ||
425 | if (sizeof(new_val) == sizeof(long)) | ||
426 | return _hypercall4(int, update_va_mapping_otherdomain, va, | ||
427 | new_val.pte, flags, domid); | ||
428 | else | ||
429 | return _hypercall5(int, update_va_mapping_otherdomain, va, | ||
430 | new_val.pte, new_val.pte >> 32, | ||
431 | flags, domid); | ||
432 | } | ||
433 | |||
434 | static inline int | ||
435 | HYPERVISOR_vm_assist(unsigned int cmd, unsigned int type) | 376 | HYPERVISOR_vm_assist(unsigned int cmd, unsigned int type) |
436 | { | 377 | { |
437 | return _hypercall2(int, vm_assist, cmd, type); | 378 | return _hypercall2(int, vm_assist, cmd, type); |
@@ -465,12 +406,6 @@ HYPERVISOR_suspend(unsigned long start_info_mfn) | |||
465 | return _hypercall3(int, sched_op, SCHEDOP_shutdown, &r, start_info_mfn); | 406 | return _hypercall3(int, sched_op, SCHEDOP_shutdown, &r, start_info_mfn); |
466 | } | 407 | } |
467 | 408 | ||
468 | static inline int | ||
469 | HYPERVISOR_nmi_op(unsigned long op, unsigned long arg) | ||
470 | { | ||
471 | return _hypercall2(int, nmi_op, op, arg); | ||
472 | } | ||
473 | |||
474 | static inline unsigned long __must_check | 409 | static inline unsigned long __must_check |
475 | HYPERVISOR_hvm_op(int op, void *arg) | 410 | HYPERVISOR_hvm_op(int op, void *arg) |
476 | { | 411 | { |
@@ -529,39 +464,6 @@ MULTI_update_va_mapping(struct multicall_entry *mcl, unsigned long va, | |||
529 | } | 464 | } |
530 | 465 | ||
531 | static inline void | 466 | static inline void |
532 | MULTI_grant_table_op(struct multicall_entry *mcl, unsigned int cmd, | ||
533 | void *uop, unsigned int count) | ||
534 | { | ||
535 | mcl->op = __HYPERVISOR_grant_table_op; | ||
536 | mcl->args[0] = cmd; | ||
537 | mcl->args[1] = (unsigned long)uop; | ||
538 | mcl->args[2] = count; | ||
539 | |||
540 | trace_xen_mc_entry(mcl, 3); | ||
541 | } | ||
542 | |||
543 | static inline void | ||
544 | MULTI_update_va_mapping_otherdomain(struct multicall_entry *mcl, unsigned long va, | ||
545 | pte_t new_val, unsigned long flags, | ||
546 | domid_t domid) | ||
547 | { | ||
548 | mcl->op = __HYPERVISOR_update_va_mapping_otherdomain; | ||
549 | mcl->args[0] = va; | ||
550 | if (sizeof(new_val) == sizeof(long)) { | ||
551 | mcl->args[1] = new_val.pte; | ||
552 | mcl->args[2] = flags; | ||
553 | mcl->args[3] = domid; | ||
554 | } else { | ||
555 | mcl->args[1] = new_val.pte; | ||
556 | mcl->args[2] = new_val.pte >> 32; | ||
557 | mcl->args[3] = flags; | ||
558 | mcl->args[4] = domid; | ||
559 | } | ||
560 | |||
561 | trace_xen_mc_entry(mcl, sizeof(new_val) == sizeof(long) ? 4 : 5); | ||
562 | } | ||
563 | |||
564 | static inline void | ||
565 | MULTI_update_descriptor(struct multicall_entry *mcl, u64 maddr, | 467 | MULTI_update_descriptor(struct multicall_entry *mcl, u64 maddr, |
566 | struct desc_struct desc) | 468 | struct desc_struct desc) |
567 | { | 469 | { |
@@ -582,16 +484,6 @@ MULTI_update_descriptor(struct multicall_entry *mcl, u64 maddr, | |||
582 | } | 484 | } |
583 | 485 | ||
584 | static inline void | 486 | static inline void |
585 | MULTI_memory_op(struct multicall_entry *mcl, unsigned int cmd, void *arg) | ||
586 | { | ||
587 | mcl->op = __HYPERVISOR_memory_op; | ||
588 | mcl->args[0] = cmd; | ||
589 | mcl->args[1] = (unsigned long)arg; | ||
590 | |||
591 | trace_xen_mc_entry(mcl, 2); | ||
592 | } | ||
593 | |||
594 | static inline void | ||
595 | MULTI_mmu_update(struct multicall_entry *mcl, struct mmu_update *req, | 487 | MULTI_mmu_update(struct multicall_entry *mcl, struct mmu_update *req, |
596 | int count, int *success_count, domid_t domid) | 488 | int count, int *success_count, domid_t domid) |
597 | { | 489 | { |
@@ -618,16 +510,6 @@ MULTI_mmuext_op(struct multicall_entry *mcl, struct mmuext_op *op, int count, | |||
618 | } | 510 | } |
619 | 511 | ||
620 | static inline void | 512 | static inline void |
621 | MULTI_set_gdt(struct multicall_entry *mcl, unsigned long *frames, int entries) | ||
622 | { | ||
623 | mcl->op = __HYPERVISOR_set_gdt; | ||
624 | mcl->args[0] = (unsigned long)frames; | ||
625 | mcl->args[1] = entries; | ||
626 | |||
627 | trace_xen_mc_entry(mcl, 2); | ||
628 | } | ||
629 | |||
630 | static inline void | ||
631 | MULTI_stack_switch(struct multicall_entry *mcl, | 513 | MULTI_stack_switch(struct multicall_entry *mcl, |
632 | unsigned long ss, unsigned long esp) | 514 | unsigned long ss, unsigned long esp) |
633 | { | 515 | { |
diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c index acfab322fbe0..5c32a7665492 100644 --- a/arch/x86/mm/init.c +++ b/arch/x86/mm/init.c | |||
@@ -99,15 +99,22 @@ __ref void *alloc_low_pages(unsigned int num) | |||
99 | } | 99 | } |
100 | 100 | ||
101 | if ((pgt_buf_end + num) > pgt_buf_top || !can_use_brk_pgt) { | 101 | if ((pgt_buf_end + num) > pgt_buf_top || !can_use_brk_pgt) { |
102 | unsigned long ret; | 102 | unsigned long ret = 0; |
103 | if (min_pfn_mapped >= max_pfn_mapped) | 103 | |
104 | panic("alloc_low_pages: ran out of memory"); | 104 | if (min_pfn_mapped < max_pfn_mapped) { |
105 | ret = memblock_find_in_range(min_pfn_mapped << PAGE_SHIFT, | 105 | ret = memblock_find_in_range( |
106 | min_pfn_mapped << PAGE_SHIFT, | ||
106 | max_pfn_mapped << PAGE_SHIFT, | 107 | max_pfn_mapped << PAGE_SHIFT, |
107 | PAGE_SIZE * num , PAGE_SIZE); | 108 | PAGE_SIZE * num , PAGE_SIZE); |
109 | } | ||
110 | if (ret) | ||
111 | memblock_reserve(ret, PAGE_SIZE * num); | ||
112 | else if (can_use_brk_pgt) | ||
113 | ret = __pa(extend_brk(PAGE_SIZE * num, PAGE_SIZE)); | ||
114 | |||
108 | if (!ret) | 115 | if (!ret) |
109 | panic("alloc_low_pages: can not alloc memory"); | 116 | panic("alloc_low_pages: can not alloc memory"); |
110 | memblock_reserve(ret, PAGE_SIZE * num); | 117 | |
111 | pfn = ret >> PAGE_SHIFT; | 118 | pfn = ret >> PAGE_SHIFT; |
112 | } else { | 119 | } else { |
113 | pfn = pgt_buf_end; | 120 | pfn = pgt_buf_end; |
diff --git a/arch/x86/xen/enlighten_pv.c b/arch/x86/xen/enlighten_pv.c index ee3b00c7acda..52a7c3faee0c 100644 --- a/arch/x86/xen/enlighten_pv.c +++ b/arch/x86/xen/enlighten_pv.c | |||
@@ -122,6 +122,8 @@ static void __init xen_banner(void) | |||
122 | 122 | ||
123 | static void __init xen_pv_init_platform(void) | 123 | static void __init xen_pv_init_platform(void) |
124 | { | 124 | { |
125 | populate_extra_pte(fix_to_virt(FIX_PARAVIRT_BOOTMAP)); | ||
126 | |||
125 | set_fixmap(FIX_PARAVIRT_BOOTMAP, xen_start_info->shared_info); | 127 | set_fixmap(FIX_PARAVIRT_BOOTMAP, xen_start_info->shared_info); |
126 | HYPERVISOR_shared_info = (void *)fix_to_virt(FIX_PARAVIRT_BOOTMAP); | 128 | HYPERVISOR_shared_info = (void *)fix_to_virt(FIX_PARAVIRT_BOOTMAP); |
127 | 129 | ||
@@ -1170,13 +1172,13 @@ static void __init xen_boot_params_init_edd(void) | |||
1170 | * we do this, we have to be careful not to call any stack-protected | 1172 | * we do this, we have to be careful not to call any stack-protected |
1171 | * function, which is most of the kernel. | 1173 | * function, which is most of the kernel. |
1172 | */ | 1174 | */ |
1173 | static void xen_setup_gdt(int cpu) | 1175 | static void __init xen_setup_gdt(int cpu) |
1174 | { | 1176 | { |
1175 | pv_cpu_ops.write_gdt_entry = xen_write_gdt_entry_boot; | 1177 | pv_cpu_ops.write_gdt_entry = xen_write_gdt_entry_boot; |
1176 | pv_cpu_ops.load_gdt = xen_load_gdt_boot; | 1178 | pv_cpu_ops.load_gdt = xen_load_gdt_boot; |
1177 | 1179 | ||
1178 | setup_stack_canary_segment(0); | 1180 | setup_stack_canary_segment(cpu); |
1179 | switch_to_new_gdt(0); | 1181 | switch_to_new_gdt(cpu); |
1180 | 1182 | ||
1181 | pv_cpu_ops.write_gdt_entry = xen_write_gdt_entry; | 1183 | pv_cpu_ops.write_gdt_entry = xen_write_gdt_entry; |
1182 | pv_cpu_ops.load_gdt = xen_load_gdt; | 1184 | pv_cpu_ops.load_gdt = xen_load_gdt; |
@@ -1385,8 +1387,11 @@ asmlinkage __visible void __init xen_start_kernel(void) | |||
1385 | xen_boot_params_init_edd(); | 1387 | xen_boot_params_init_edd(); |
1386 | } | 1388 | } |
1387 | 1389 | ||
1388 | add_preferred_console("tty", 0, NULL); | 1390 | if (!boot_params.screen_info.orig_video_isVGA) |
1391 | add_preferred_console("tty", 0, NULL); | ||
1389 | add_preferred_console("hvc", 0, NULL); | 1392 | add_preferred_console("hvc", 0, NULL); |
1393 | if (boot_params.screen_info.orig_video_isVGA) | ||
1394 | add_preferred_console("tty", 0, NULL); | ||
1390 | 1395 | ||
1391 | #ifdef CONFIG_PCI | 1396 | #ifdef CONFIG_PCI |
1392 | /* PCI BIOS service won't work from a PV guest. */ | 1397 | /* PCI BIOS service won't work from a PV guest. */ |
diff --git a/arch/x86/xen/mmu_pv.c b/arch/x86/xen/mmu_pv.c index 52206ad81e4b..9e7012858420 100644 --- a/arch/x86/xen/mmu_pv.c +++ b/arch/x86/xen/mmu_pv.c | |||
@@ -2171,6 +2171,8 @@ void __init xen_relocate_p2m(void) | |||
2171 | #else /* !CONFIG_X86_64 */ | 2171 | #else /* !CONFIG_X86_64 */ |
2172 | static RESERVE_BRK_ARRAY(pmd_t, initial_kernel_pmd, PTRS_PER_PMD); | 2172 | static RESERVE_BRK_ARRAY(pmd_t, initial_kernel_pmd, PTRS_PER_PMD); |
2173 | static RESERVE_BRK_ARRAY(pmd_t, swapper_kernel_pmd, PTRS_PER_PMD); | 2173 | static RESERVE_BRK_ARRAY(pmd_t, swapper_kernel_pmd, PTRS_PER_PMD); |
2174 | RESERVE_BRK(fixup_kernel_pmd, PAGE_SIZE); | ||
2175 | RESERVE_BRK(fixup_kernel_pte, PAGE_SIZE); | ||
2174 | 2176 | ||
2175 | static void __init xen_write_cr3_init(unsigned long cr3) | 2177 | static void __init xen_write_cr3_init(unsigned long cr3) |
2176 | { | 2178 | { |
diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c index 6e0d2086eacb..1163e33121fb 100644 --- a/arch/x86/xen/setup.c +++ b/arch/x86/xen/setup.c | |||
@@ -906,37 +906,6 @@ char * __init xen_memory_setup(void) | |||
906 | } | 906 | } |
907 | 907 | ||
908 | /* | 908 | /* |
909 | * Machine specific memory setup for auto-translated guests. | ||
910 | */ | ||
911 | char * __init xen_auto_xlated_memory_setup(void) | ||
912 | { | ||
913 | struct xen_memory_map memmap; | ||
914 | int i; | ||
915 | int rc; | ||
916 | |||
917 | memmap.nr_entries = ARRAY_SIZE(xen_e820_table.entries); | ||
918 | set_xen_guest_handle(memmap.buffer, xen_e820_table.entries); | ||
919 | |||
920 | rc = HYPERVISOR_memory_op(XENMEM_memory_map, &memmap); | ||
921 | if (rc < 0) | ||
922 | panic("No memory map (%d)\n", rc); | ||
923 | |||
924 | xen_e820_table.nr_entries = memmap.nr_entries; | ||
925 | |||
926 | e820__update_table(&xen_e820_table); | ||
927 | |||
928 | for (i = 0; i < xen_e820_table.nr_entries; i++) | ||
929 | e820__range_add(xen_e820_table.entries[i].addr, xen_e820_table.entries[i].size, xen_e820_table.entries[i].type); | ||
930 | |||
931 | /* Remove p2m info, it is not needed. */ | ||
932 | xen_start_info->mfn_list = 0; | ||
933 | xen_start_info->first_p2m_pfn = 0; | ||
934 | xen_start_info->nr_p2m_frames = 0; | ||
935 | |||
936 | return "Xen"; | ||
937 | } | ||
938 | |||
939 | /* | ||
940 | * Set the bit indicating "nosegneg" library variants should be used. | 909 | * Set the bit indicating "nosegneg" library variants should be used. |
941 | * We only need to bother in pure 32-bit mode; compat 32-bit processes | 910 | * We only need to bother in pure 32-bit mode; compat 32-bit processes |
942 | * can have un-truncated segments, so wrapping around is allowed. | 911 | * can have un-truncated segments, so wrapping around is allowed. |
diff --git a/arch/x86/xen/xen-ops.h b/arch/x86/xen/xen-ops.h index e78684597f57..0e60bd918695 100644 --- a/arch/x86/xen/xen-ops.h +++ b/arch/x86/xen/xen-ops.h | |||
@@ -50,7 +50,6 @@ void __init xen_inv_extra_mem(void); | |||
50 | void __init xen_remap_memory(void); | 50 | void __init xen_remap_memory(void); |
51 | phys_addr_t __init xen_find_free_area(phys_addr_t size); | 51 | phys_addr_t __init xen_find_free_area(phys_addr_t size); |
52 | char * __init xen_memory_setup(void); | 52 | char * __init xen_memory_setup(void); |
53 | char * xen_auto_xlated_memory_setup(void); | ||
54 | void __init xen_arch_setup(void); | 53 | void __init xen_arch_setup(void); |
55 | void xen_enable_sysenter(void); | 54 | void xen_enable_sysenter(void); |
56 | void xen_enable_syscall(void); | 55 | void xen_enable_syscall(void); |
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index b933061b6b60..8c0a54d50d0e 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c | |||
@@ -205,6 +205,7 @@ phys_cpuid_t acpi_get_phys_id(acpi_handle handle, int type, u32 acpi_id) | |||
205 | 205 | ||
206 | return phys_id; | 206 | return phys_id; |
207 | } | 207 | } |
208 | EXPORT_SYMBOL_GPL(acpi_get_phys_id); | ||
208 | 209 | ||
209 | int acpi_map_cpuid(phys_cpuid_t phys_id, u32 acpi_id) | 210 | int acpi_map_cpuid(phys_cpuid_t phys_id, u32 acpi_id) |
210 | { | 211 | { |
diff --git a/drivers/xen/mcelog.c b/drivers/xen/mcelog.c index 262835ace35d..b8bf61abb65b 100644 --- a/drivers/xen/mcelog.c +++ b/drivers/xen/mcelog.c | |||
@@ -288,7 +288,6 @@ static int mc_queue_handle(uint32_t flags) | |||
288 | int ret = 0; | 288 | int ret = 0; |
289 | 289 | ||
290 | mc_op.cmd = XEN_MC_fetch; | 290 | mc_op.cmd = XEN_MC_fetch; |
291 | mc_op.interface_version = XEN_MCA_INTERFACE_VERSION; | ||
292 | set_xen_guest_handle(mc_op.u.mc_fetch.data, &g_mi); | 291 | set_xen_guest_handle(mc_op.u.mc_fetch.data, &g_mi); |
293 | do { | 292 | do { |
294 | mc_op.u.mc_fetch.flags = flags; | 293 | mc_op.u.mc_fetch.flags = flags; |
@@ -358,7 +357,6 @@ static int bind_virq_for_mce(void) | |||
358 | 357 | ||
359 | /* Fetch physical CPU Numbers */ | 358 | /* Fetch physical CPU Numbers */ |
360 | mc_op.cmd = XEN_MC_physcpuinfo; | 359 | mc_op.cmd = XEN_MC_physcpuinfo; |
361 | mc_op.interface_version = XEN_MCA_INTERFACE_VERSION; | ||
362 | set_xen_guest_handle(mc_op.u.mc_physcpuinfo.info, g_physinfo); | 360 | set_xen_guest_handle(mc_op.u.mc_physcpuinfo.info, g_physinfo); |
363 | ret = HYPERVISOR_mca(&mc_op); | 361 | ret = HYPERVISOR_mca(&mc_op); |
364 | if (ret) { | 362 | if (ret) { |
diff --git a/drivers/xen/xen-acpi-processor.c b/drivers/xen/xen-acpi-processor.c index b29f4e40851f..fbb9137c7d02 100644 --- a/drivers/xen/xen-acpi-processor.c +++ b/drivers/xen/xen-acpi-processor.c | |||
@@ -362,6 +362,12 @@ read_acpi_id(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
362 | default: | 362 | default: |
363 | return AE_OK; | 363 | return AE_OK; |
364 | } | 364 | } |
365 | if (invalid_phys_cpuid(acpi_get_phys_id(handle, | ||
366 | acpi_type == ACPI_TYPE_DEVICE, | ||
367 | acpi_id))) { | ||
368 | pr_debug("CPU with ACPI ID %u is unavailable\n", acpi_id); | ||
369 | return AE_OK; | ||
370 | } | ||
365 | /* There are more ACPI Processor objects than in x2APIC or MADT. | 371 | /* There are more ACPI Processor objects than in x2APIC or MADT. |
366 | * This can happen with incorrect ACPI SSDT declerations. */ | 372 | * This can happen with incorrect ACPI SSDT declerations. */ |
367 | if (acpi_id >= nr_acpi_bits) { | 373 | if (acpi_id >= nr_acpi_bits) { |