diff options
Diffstat (limited to 'arch/sparc')
-rw-r--r-- | arch/sparc/configs/sparc64_defconfig | 1 | ||||
-rw-r--r-- | arch/sparc/include/asm/Kbuild | 1 | ||||
-rw-r--r-- | arch/sparc/include/asm/vio.h | 44 | ||||
-rw-r--r-- | arch/sparc/include/uapi/asm/ioctls.h | 2 | ||||
-rw-r--r-- | arch/sparc/kernel/ldc.c | 2 | ||||
-rw-r--r-- | arch/sparc/kernel/viohs.c | 14 | ||||
-rw-r--r-- | arch/sparc/net/bpf_jit_asm.S | 3 | ||||
-rw-r--r-- | arch/sparc/net/bpf_jit_comp.c | 48 | ||||
-rw-r--r-- | arch/sparc/power/hibernate.c | 4 |
9 files changed, 93 insertions, 26 deletions
diff --git a/arch/sparc/configs/sparc64_defconfig b/arch/sparc/configs/sparc64_defconfig index 9d8521b8c854..6b68f12f29db 100644 --- a/arch/sparc/configs/sparc64_defconfig +++ b/arch/sparc/configs/sparc64_defconfig | |||
@@ -29,6 +29,7 @@ CONFIG_PCI=y | |||
29 | CONFIG_PCI_MSI=y | 29 | CONFIG_PCI_MSI=y |
30 | CONFIG_SUN_OPENPROMFS=m | 30 | CONFIG_SUN_OPENPROMFS=m |
31 | CONFIG_BINFMT_MISC=m | 31 | CONFIG_BINFMT_MISC=m |
32 | CONFIG_NET=y | ||
32 | CONFIG_PACKET=y | 33 | CONFIG_PACKET=y |
33 | CONFIG_UNIX=y | 34 | CONFIG_UNIX=y |
34 | CONFIG_XFRM_USER=m | 35 | CONFIG_XFRM_USER=m |
diff --git a/arch/sparc/include/asm/Kbuild b/arch/sparc/include/asm/Kbuild index cdd1b447bb6c..f5f94ce1692c 100644 --- a/arch/sparc/include/asm/Kbuild +++ b/arch/sparc/include/asm/Kbuild | |||
@@ -8,6 +8,7 @@ generic-y += emergency-restart.h | |||
8 | generic-y += exec.h | 8 | generic-y += exec.h |
9 | generic-y += hash.h | 9 | generic-y += hash.h |
10 | generic-y += irq_regs.h | 10 | generic-y += irq_regs.h |
11 | generic-y += irq_work.h | ||
11 | generic-y += linkage.h | 12 | generic-y += linkage.h |
12 | generic-y += local.h | 13 | generic-y += local.h |
13 | generic-y += local64.h | 14 | generic-y += local64.h |
diff --git a/arch/sparc/include/asm/vio.h b/arch/sparc/include/asm/vio.h index e0f6c399f1d0..6b135a8ab07b 100644 --- a/arch/sparc/include/asm/vio.h +++ b/arch/sparc/include/asm/vio.h | |||
@@ -65,6 +65,7 @@ struct vio_dring_register { | |||
65 | u16 options; | 65 | u16 options; |
66 | #define VIO_TX_DRING 0x0001 | 66 | #define VIO_TX_DRING 0x0001 |
67 | #define VIO_RX_DRING 0x0002 | 67 | #define VIO_RX_DRING 0x0002 |
68 | #define VIO_RX_DRING_DATA 0x0004 | ||
68 | u16 resv; | 69 | u16 resv; |
69 | u32 num_cookies; | 70 | u32 num_cookies; |
70 | struct ldc_trans_cookie cookies[0]; | 71 | struct ldc_trans_cookie cookies[0]; |
@@ -80,6 +81,8 @@ struct vio_dring_unregister { | |||
80 | #define VIO_PKT_MODE 0x01 /* Packet based transfer */ | 81 | #define VIO_PKT_MODE 0x01 /* Packet based transfer */ |
81 | #define VIO_DESC_MODE 0x02 /* In-band descriptors */ | 82 | #define VIO_DESC_MODE 0x02 /* In-band descriptors */ |
82 | #define VIO_DRING_MODE 0x03 /* Descriptor rings */ | 83 | #define VIO_DRING_MODE 0x03 /* Descriptor rings */ |
84 | /* in vers >= 1.2, VIO_DRING_MODE is 0x04 and transfer mode is a bitmask */ | ||
85 | #define VIO_NEW_DRING_MODE 0x04 | ||
83 | 86 | ||
84 | struct vio_dring_data { | 87 | struct vio_dring_data { |
85 | struct vio_msg_tag tag; | 88 | struct vio_msg_tag tag; |
@@ -205,10 +208,20 @@ struct vio_net_attr_info { | |||
205 | u8 addr_type; | 208 | u8 addr_type; |
206 | #define VNET_ADDR_ETHERMAC 0x01 | 209 | #define VNET_ADDR_ETHERMAC 0x01 |
207 | u16 ack_freq; | 210 | u16 ack_freq; |
208 | u32 resv1; | 211 | u8 plnk_updt; |
212 | #define PHYSLINK_UPDATE_NONE 0x00 | ||
213 | #define PHYSLINK_UPDATE_STATE 0x01 | ||
214 | #define PHYSLINK_UPDATE_STATE_ACK 0x02 | ||
215 | #define PHYSLINK_UPDATE_STATE_NACK 0x03 | ||
216 | u8 options; | ||
217 | u16 resv1; | ||
209 | u64 addr; | 218 | u64 addr; |
210 | u64 mtu; | 219 | u64 mtu; |
211 | u64 resv2[3]; | 220 | u16 cflags; |
221 | #define VNET_LSO_IPV4_CAPAB 0x0001 | ||
222 | u16 ipv4_lso_maxlen; | ||
223 | u32 resv2; | ||
224 | u64 resv3[2]; | ||
212 | }; | 225 | }; |
213 | 226 | ||
214 | #define VNET_NUM_MCAST 7 | 227 | #define VNET_NUM_MCAST 7 |
@@ -366,6 +379,33 @@ struct vio_driver_state { | |||
366 | struct vio_driver_ops *ops; | 379 | struct vio_driver_ops *ops; |
367 | }; | 380 | }; |
368 | 381 | ||
382 | static inline bool vio_version_before(struct vio_driver_state *vio, | ||
383 | u16 major, u16 minor) | ||
384 | { | ||
385 | u32 have = (u32)vio->ver.major << 16 | vio->ver.minor; | ||
386 | u32 want = (u32)major << 16 | minor; | ||
387 | |||
388 | return have < want; | ||
389 | } | ||
390 | |||
391 | static inline bool vio_version_after(struct vio_driver_state *vio, | ||
392 | u16 major, u16 minor) | ||
393 | { | ||
394 | u32 have = (u32)vio->ver.major << 16 | vio->ver.minor; | ||
395 | u32 want = (u32)major << 16 | minor; | ||
396 | |||
397 | return have > want; | ||
398 | } | ||
399 | |||
400 | static inline bool vio_version_after_eq(struct vio_driver_state *vio, | ||
401 | u16 major, u16 minor) | ||
402 | { | ||
403 | u32 have = (u32)vio->ver.major << 16 | vio->ver.minor; | ||
404 | u32 want = (u32)major << 16 | minor; | ||
405 | |||
406 | return have >= want; | ||
407 | } | ||
408 | |||
369 | #define viodbg(TYPE, f, a...) \ | 409 | #define viodbg(TYPE, f, a...) \ |
370 | do { if (vio->debug & VIO_DEBUG_##TYPE) \ | 410 | do { if (vio->debug & VIO_DEBUG_##TYPE) \ |
371 | printk(KERN_INFO "vio: ID[%lu] " f, \ | 411 | printk(KERN_INFO "vio: ID[%lu] " f, \ |
diff --git a/arch/sparc/include/uapi/asm/ioctls.h b/arch/sparc/include/uapi/asm/ioctls.h index 897d1723fa14..06b3f6c3bb9a 100644 --- a/arch/sparc/include/uapi/asm/ioctls.h +++ b/arch/sparc/include/uapi/asm/ioctls.h | |||
@@ -24,6 +24,8 @@ | |||
24 | #define TIOCGPKT _IOR('T', 0x38, int) /* Get packet mode state */ | 24 | #define TIOCGPKT _IOR('T', 0x38, int) /* Get packet mode state */ |
25 | #define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */ | 25 | #define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */ |
26 | #define TIOCGEXCL _IOR('T', 0x40, int) /* Get exclusive mode state */ | 26 | #define TIOCGEXCL _IOR('T', 0x40, int) /* Get exclusive mode state */ |
27 | #define TIOCGRS485 _IOR('T', 0x41, struct serial_rs485) | ||
28 | #define TIOCSRS485 _IOWR('T', 0x42, struct serial_rs485) | ||
27 | 29 | ||
28 | /* Note that all the ioctls that are not available in Linux have a | 30 | /* Note that all the ioctls that are not available in Linux have a |
29 | * double underscore on the front to: a) avoid some programs to | 31 | * double underscore on the front to: a) avoid some programs to |
diff --git a/arch/sparc/kernel/ldc.c b/arch/sparc/kernel/ldc.c index 66dacd56bb10..0af28b984695 100644 --- a/arch/sparc/kernel/ldc.c +++ b/arch/sparc/kernel/ldc.c | |||
@@ -2159,7 +2159,7 @@ int ldc_map_single(struct ldc_channel *lp, | |||
2159 | state.pte_idx = (base - iommu->page_table); | 2159 | state.pte_idx = (base - iommu->page_table); |
2160 | state.nc = 0; | 2160 | state.nc = 0; |
2161 | fill_cookies(&state, (pa & PAGE_MASK), (pa & ~PAGE_MASK), len); | 2161 | fill_cookies(&state, (pa & PAGE_MASK), (pa & ~PAGE_MASK), len); |
2162 | BUG_ON(state.nc != 1); | 2162 | BUG_ON(state.nc > ncookies); |
2163 | 2163 | ||
2164 | return state.nc; | 2164 | return state.nc; |
2165 | } | 2165 | } |
diff --git a/arch/sparc/kernel/viohs.c b/arch/sparc/kernel/viohs.c index f8e7dd53e1c7..7ef081a185b1 100644 --- a/arch/sparc/kernel/viohs.c +++ b/arch/sparc/kernel/viohs.c | |||
@@ -426,6 +426,13 @@ static int process_dreg_info(struct vio_driver_state *vio, | |||
426 | if (vio->dr_state & VIO_DR_STATE_RXREG) | 426 | if (vio->dr_state & VIO_DR_STATE_RXREG) |
427 | goto send_nack; | 427 | goto send_nack; |
428 | 428 | ||
429 | /* v1.6 and higher, ACK with desired, supported mode, or NACK */ | ||
430 | if (vio_version_after_eq(vio, 1, 6)) { | ||
431 | if (!(pkt->options & VIO_TX_DRING)) | ||
432 | goto send_nack; | ||
433 | pkt->options = VIO_TX_DRING; | ||
434 | } | ||
435 | |||
429 | BUG_ON(vio->desc_buf); | 436 | BUG_ON(vio->desc_buf); |
430 | 437 | ||
431 | vio->desc_buf = kzalloc(pkt->descr_size, GFP_ATOMIC); | 438 | vio->desc_buf = kzalloc(pkt->descr_size, GFP_ATOMIC); |
@@ -453,8 +460,11 @@ static int process_dreg_info(struct vio_driver_state *vio, | |||
453 | pkt->tag.stype = VIO_SUBTYPE_ACK; | 460 | pkt->tag.stype = VIO_SUBTYPE_ACK; |
454 | pkt->dring_ident = ++dr->ident; | 461 | pkt->dring_ident = ++dr->ident; |
455 | 462 | ||
456 | viodbg(HS, "SEND DRING_REG ACK ident[%llx]\n", | 463 | viodbg(HS, "SEND DRING_REG ACK ident[%llx] " |
457 | (unsigned long long) pkt->dring_ident); | 464 | "ndesc[%u] dsz[%u] opt[0x%x] ncookies[%u]\n", |
465 | (unsigned long long) pkt->dring_ident, | ||
466 | pkt->num_descr, pkt->descr_size, pkt->options, | ||
467 | pkt->num_cookies); | ||
458 | 468 | ||
459 | len = (sizeof(*pkt) + | 469 | len = (sizeof(*pkt) + |
460 | (dr->ncookies * sizeof(struct ldc_trans_cookie))); | 470 | (dr->ncookies * sizeof(struct ldc_trans_cookie))); |
diff --git a/arch/sparc/net/bpf_jit_asm.S b/arch/sparc/net/bpf_jit_asm.S index 9d016c7017f7..8c83f4b8eb15 100644 --- a/arch/sparc/net/bpf_jit_asm.S +++ b/arch/sparc/net/bpf_jit_asm.S | |||
@@ -6,10 +6,12 @@ | |||
6 | #define SAVE_SZ 176 | 6 | #define SAVE_SZ 176 |
7 | #define SCRATCH_OFF STACK_BIAS + 128 | 7 | #define SCRATCH_OFF STACK_BIAS + 128 |
8 | #define BE_PTR(label) be,pn %xcc, label | 8 | #define BE_PTR(label) be,pn %xcc, label |
9 | #define SIGN_EXTEND(reg) sra reg, 0, reg | ||
9 | #else | 10 | #else |
10 | #define SAVE_SZ 96 | 11 | #define SAVE_SZ 96 |
11 | #define SCRATCH_OFF 72 | 12 | #define SCRATCH_OFF 72 |
12 | #define BE_PTR(label) be label | 13 | #define BE_PTR(label) be label |
14 | #define SIGN_EXTEND(reg) | ||
13 | #endif | 15 | #endif |
14 | 16 | ||
15 | #define SKF_MAX_NEG_OFF (-0x200000) /* SKF_LL_OFF from filter.h */ | 17 | #define SKF_MAX_NEG_OFF (-0x200000) /* SKF_LL_OFF from filter.h */ |
@@ -135,6 +137,7 @@ bpf_slow_path_byte_msh: | |||
135 | save %sp, -SAVE_SZ, %sp; \ | 137 | save %sp, -SAVE_SZ, %sp; \ |
136 | mov %i0, %o0; \ | 138 | mov %i0, %o0; \ |
137 | mov r_OFF, %o1; \ | 139 | mov r_OFF, %o1; \ |
140 | SIGN_EXTEND(%o1); \ | ||
138 | call bpf_internal_load_pointer_neg_helper; \ | 141 | call bpf_internal_load_pointer_neg_helper; \ |
139 | mov (LEN), %o2; \ | 142 | mov (LEN), %o2; \ |
140 | mov %o0, r_TMP; \ | 143 | mov %o0, r_TMP; \ |
diff --git a/arch/sparc/net/bpf_jit_comp.c b/arch/sparc/net/bpf_jit_comp.c index 1f76c22a6a75..f33e7c7a3bf7 100644 --- a/arch/sparc/net/bpf_jit_comp.c +++ b/arch/sparc/net/bpf_jit_comp.c | |||
@@ -184,7 +184,7 @@ do { \ | |||
184 | */ | 184 | */ |
185 | #define emit_alu_K(OPCODE, K) \ | 185 | #define emit_alu_K(OPCODE, K) \ |
186 | do { \ | 186 | do { \ |
187 | if (K) { \ | 187 | if (K || OPCODE == AND || OPCODE == MUL) { \ |
188 | unsigned int _insn = OPCODE; \ | 188 | unsigned int _insn = OPCODE; \ |
189 | _insn |= RS1(r_A) | RD(r_A); \ | 189 | _insn |= RS1(r_A) | RD(r_A); \ |
190 | if (is_simm13(K)) { \ | 190 | if (is_simm13(K)) { \ |
@@ -234,12 +234,18 @@ do { BUILD_BUG_ON(FIELD_SIZEOF(STRUCT, FIELD) != sizeof(u8)); \ | |||
234 | __emit_load8(BASE, STRUCT, FIELD, DEST); \ | 234 | __emit_load8(BASE, STRUCT, FIELD, DEST); \ |
235 | } while (0) | 235 | } while (0) |
236 | 236 | ||
237 | #define emit_ldmem(OFF, DEST) \ | 237 | #ifdef CONFIG_SPARC64 |
238 | do { *prog++ = LD32I | RS1(FP) | S13(-(OFF)) | RD(DEST); \ | 238 | #define BIAS (STACK_BIAS - 4) |
239 | #else | ||
240 | #define BIAS (-4) | ||
241 | #endif | ||
242 | |||
243 | #define emit_ldmem(OFF, DEST) \ | ||
244 | do { *prog++ = LD32I | RS1(SP) | S13(BIAS - (OFF)) | RD(DEST); \ | ||
239 | } while (0) | 245 | } while (0) |
240 | 246 | ||
241 | #define emit_stmem(OFF, SRC) \ | 247 | #define emit_stmem(OFF, SRC) \ |
242 | do { *prog++ = LD32I | RS1(FP) | S13(-(OFF)) | RD(SRC); \ | 248 | do { *prog++ = ST32I | RS1(SP) | S13(BIAS - (OFF)) | RD(SRC); \ |
243 | } while (0) | 249 | } while (0) |
244 | 250 | ||
245 | #ifdef CONFIG_SMP | 251 | #ifdef CONFIG_SMP |
@@ -579,16 +585,11 @@ void bpf_jit_compile(struct bpf_prog *fp) | |||
579 | case BPF_ANC | SKF_AD_PROTOCOL: | 585 | case BPF_ANC | SKF_AD_PROTOCOL: |
580 | emit_skb_load16(protocol, r_A); | 586 | emit_skb_load16(protocol, r_A); |
581 | break; | 587 | break; |
582 | #if 0 | ||
583 | /* GCC won't let us take the address of | ||
584 | * a bit field even though we very much | ||
585 | * know what we are doing here. | ||
586 | */ | ||
587 | case BPF_ANC | SKF_AD_PKTTYPE: | 588 | case BPF_ANC | SKF_AD_PKTTYPE: |
588 | __emit_skb_load8(pkt_type, r_A); | 589 | __emit_skb_load8(__pkt_type_offset, r_A); |
590 | emit_andi(r_A, PKT_TYPE_MAX, r_A); | ||
589 | emit_alu_K(SRL, 5); | 591 | emit_alu_K(SRL, 5); |
590 | break; | 592 | break; |
591 | #endif | ||
592 | case BPF_ANC | SKF_AD_IFINDEX: | 593 | case BPF_ANC | SKF_AD_IFINDEX: |
593 | emit_skb_loadptr(dev, r_A); | 594 | emit_skb_loadptr(dev, r_A); |
594 | emit_cmpi(r_A, 0); | 595 | emit_cmpi(r_A, 0); |
@@ -615,14 +616,20 @@ void bpf_jit_compile(struct bpf_prog *fp) | |||
615 | case BPF_ANC | SKF_AD_VLAN_TAG: | 616 | case BPF_ANC | SKF_AD_VLAN_TAG: |
616 | case BPF_ANC | SKF_AD_VLAN_TAG_PRESENT: | 617 | case BPF_ANC | SKF_AD_VLAN_TAG_PRESENT: |
617 | emit_skb_load16(vlan_tci, r_A); | 618 | emit_skb_load16(vlan_tci, r_A); |
618 | if (code == (BPF_ANC | SKF_AD_VLAN_TAG)) { | 619 | if (code != (BPF_ANC | SKF_AD_VLAN_TAG)) { |
619 | emit_andi(r_A, VLAN_VID_MASK, r_A); | 620 | emit_alu_K(SRL, 12); |
621 | emit_andi(r_A, 1, r_A); | ||
620 | } else { | 622 | } else { |
621 | emit_loadimm(VLAN_TAG_PRESENT, r_TMP); | 623 | emit_loadimm(~VLAN_TAG_PRESENT, r_TMP); |
622 | emit_and(r_A, r_TMP, r_A); | 624 | emit_and(r_A, r_TMP, r_A); |
623 | } | 625 | } |
624 | break; | 626 | break; |
625 | 627 | case BPF_LD | BPF_W | BPF_LEN: | |
628 | emit_skb_load32(len, r_A); | ||
629 | break; | ||
630 | case BPF_LDX | BPF_W | BPF_LEN: | ||
631 | emit_skb_load32(len, r_X); | ||
632 | break; | ||
626 | case BPF_LD | BPF_IMM: | 633 | case BPF_LD | BPF_IMM: |
627 | emit_loadimm(K, r_A); | 634 | emit_loadimm(K, r_A); |
628 | break; | 635 | break; |
@@ -630,15 +637,19 @@ void bpf_jit_compile(struct bpf_prog *fp) | |||
630 | emit_loadimm(K, r_X); | 637 | emit_loadimm(K, r_X); |
631 | break; | 638 | break; |
632 | case BPF_LD | BPF_MEM: | 639 | case BPF_LD | BPF_MEM: |
640 | seen |= SEEN_MEM; | ||
633 | emit_ldmem(K * 4, r_A); | 641 | emit_ldmem(K * 4, r_A); |
634 | break; | 642 | break; |
635 | case BPF_LDX | BPF_MEM: | 643 | case BPF_LDX | BPF_MEM: |
644 | seen |= SEEN_MEM | SEEN_XREG; | ||
636 | emit_ldmem(K * 4, r_X); | 645 | emit_ldmem(K * 4, r_X); |
637 | break; | 646 | break; |
638 | case BPF_ST: | 647 | case BPF_ST: |
648 | seen |= SEEN_MEM; | ||
639 | emit_stmem(K * 4, r_A); | 649 | emit_stmem(K * 4, r_A); |
640 | break; | 650 | break; |
641 | case BPF_STX: | 651 | case BPF_STX: |
652 | seen |= SEEN_MEM | SEEN_XREG; | ||
642 | emit_stmem(K * 4, r_X); | 653 | emit_stmem(K * 4, r_X); |
643 | break; | 654 | break; |
644 | 655 | ||
@@ -801,7 +812,7 @@ cond_branch: f_offset = addrs[i + filter[i].jf]; | |||
801 | if (image) { | 812 | if (image) { |
802 | bpf_flush_icache(image, image + proglen); | 813 | bpf_flush_icache(image, image + proglen); |
803 | fp->bpf_func = (void *)image; | 814 | fp->bpf_func = (void *)image; |
804 | fp->jited = 1; | 815 | fp->jited = true; |
805 | } | 816 | } |
806 | out: | 817 | out: |
807 | kfree(addrs); | 818 | kfree(addrs); |
@@ -812,5 +823,6 @@ void bpf_jit_free(struct bpf_prog *fp) | |||
812 | { | 823 | { |
813 | if (fp->jited) | 824 | if (fp->jited) |
814 | module_free(NULL, fp->bpf_func); | 825 | module_free(NULL, fp->bpf_func); |
815 | kfree(fp); | 826 | |
827 | bpf_prog_unlock_free(fp); | ||
816 | } | 828 | } |
diff --git a/arch/sparc/power/hibernate.c b/arch/sparc/power/hibernate.c index 42b0b8ce699a..17bd2e167e07 100644 --- a/arch/sparc/power/hibernate.c +++ b/arch/sparc/power/hibernate.c | |||
@@ -9,11 +9,9 @@ | |||
9 | #include <asm/hibernate.h> | 9 | #include <asm/hibernate.h> |
10 | #include <asm/visasm.h> | 10 | #include <asm/visasm.h> |
11 | #include <asm/page.h> | 11 | #include <asm/page.h> |
12 | #include <asm/sections.h> | ||
12 | #include <asm/tlb.h> | 13 | #include <asm/tlb.h> |
13 | 14 | ||
14 | /* References to section boundaries */ | ||
15 | extern const void __nosave_begin, __nosave_end; | ||
16 | |||
17 | struct saved_context saved_context; | 15 | struct saved_context saved_context; |
18 | 16 | ||
19 | /* | 17 | /* |