Netdev List
 help / color / mirror / Atom feed
* Re: [REGRESSION][PATCH] bpf_jit drops the ball on indirect negative mem references
From: Matt Evans @ 2012-03-30 15:19 UTC (permalink / raw)
  To: Jan Seiffert
  Cc: <netdev@vger.kernel.org>, Eric Dumazet,
	<linux-kernel@vger.kernel.org>, David S. Miller
In-Reply-To: <4F75B828.3090705@googlemail.com>

Hi Jan,

On 30 Mar 2012, at 14:42, Jan Seiffert <kaffeemonster@googlemail.com> wrote:

> Eric Dumazet schrieb:
>> [snip]
>> All these ".p2align 1" are noise for this patch.
>> 
>> This should be done as separate patch, explaining the rationale.
>> 
>> ...
> Ok, i thought since you where concerned with the performance and
> I'm touching this stuff anyway.
> But you are right, can be done separately.
> So gone.
> 
>> [snip]
>> 
>> Please add the code for imm8 offsets as well ?
>> 
>> if (is_imm8(K))
>>    EMIT3(0x8d, 0x73, K); /* lea imm8(%rbx),%esi */
>> else
>>    EMIT2_off32(0x8d, 0xb3, K); /* lea imm32(%rbx),%esi */
> 
> Right, there is this imm8 form. I left it out because i never saw gas emit it
> and totally forgot about it.
> Your wish is my command. But since there is no EMIT2_off32 and introducing
> it would mean additional cleanup noise, i stayed with two emits.
> 
> Do you know where i can ping the powerpc guys a little bit harder?

No need (unless you mean a different guy), I have enough guilt as it is! :) (Sorry for no response, am moving house and am netless.) I skimmed your patches on my phone but hope to be in a state to review/test over the weekend or early next week. :)


Cheers,

Matt


> 
> So here a v3 of the patch:
> 
> Consider the following test program:
> 
> #include <stdio.h>
> #include <sys/types.h>
> #include <sys/socket.h>
> #include <netinet/in.h>
> #include <pcap-bpf.h>
> 
> #define die(x) do {perror(x); return 1;} while (0)
> struct bpf_insn udp_filter[] = {
>    /*   0 */ BPF_STMT(BPF_LDX|BPF_W|BPF_IMM, -1048576+(0)), /* leax    net[0] */
>    /*   1 */ BPF_STMT(BPF_LD|BPF_B|BPF_IND, 0),             /* ldb    [x+0] */
>    /*   2 */ BPF_STMT(BPF_RET|BPF_A, 0),                    /* ret    a */
> };
> 
> int main(int argc, char *argv[])
> {
>    char buf[512];
>    struct sockaddr_in addr;
>    struct bpf_program prg;
>    socklen_t addr_s;
>    ssize_t res;
>    int fd;
> 
>    addr.sin_family = AF_INET;
>    addr.sin_port = htons(5000);
>    addr.sin_addr.s_addr = 0;
>    addr_s = sizeof(addr);
>    prg.bf_len = sizeof(udp_filter)/sizeof(udp_filter[0]);
>    prg.bf_insns = udp_filter;
>    if(-1 == (fd = socket(AF_INET, SOCK_DGRAM, 0)))
>        die("socket");
>    if(-1 == bind(fd, (struct sockaddr *)&addr, sizeof(addr)))
>        die("bind");
>    if(-1 == setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &prg, sizeof(prg)))
>        die("setsockopt");
>    res = recvfrom(fd, buf, sizeof(buf), 0, (struct sockaddr *)&addr, &addr_s);
>    if(res != -1)
>        printf("packet received: %zi bytes\n", res);
>    else
>        die("recvfrom");
>    return 0;
> }
> 
> when used with the bpf jit disabled works:
> console 1 $ ./bpf
> console 2 $ echo "hello" | nc -u localhost 5000
> console 1: packet received: 6 bytes
> 
> When the bpf jit gets enabled (echo 100 >
> /proc/sys/net/core/bpf_jit_enable) the same program stops working:
> console 1 $ ./bpf
> console 2 $ echo "hello" | nc -u localhost 5000
> console 1:
> 
> The reason is that both jits (x86 and powerpc) do not handle negative
> memory references like SKF_NET_OFF or SKF_LL_OFF, only the simple
> ancillary data references are supported (by mapping to special
> instructions).
> In the case of an absolute reference, the jit aborts the translation
> if a negative reference is seen, also a negative k on the indirect
> load aborts the translation, but if X is negative to begin with, only
> the error handler is reached at runtime which drops the whole packet.
> 
> I propose the following patch to fix this situation.
> Lightly tested on x86, but the powerpc asm part is prop. wrong.
> 
> Signed-of-by: Jan Seiffert <kaffeemonster@googlemail.com>
> 
> diff --git a/arch/powerpc/net/bpf_jit.h b/arch/powerpc/net/bpf_jit.h
> index af1ab5e..e9b57b3 100644
> --- a/arch/powerpc/net/bpf_jit.h
> +++ b/arch/powerpc/net/bpf_jit.h
> @@ -49,6 +49,10 @@
>  * Assembly helpers from arch/powerpc/net/bpf_jit.S:
>  */
> extern u8 sk_load_word[], sk_load_half[], sk_load_byte[], sk_load_byte_msh[];
> +extern u8 sk_load_word_positive_offset[], sk_load_half_positive_offset[];
> +extern u8 sk_load_byte_positive_offset[], sk_load_byte_msh_positive_offset[];
> +extern u8 sk_load_word_negative_offset[], sk_load_half_negative_offset[];
> +extern u8 sk_load_byte_negative_offset[], sk_load_byte_msh_negative_offset[];
> 
> #define FUNCTION_DESCR_SIZE    24
> 
> diff --git a/arch/powerpc/net/bpf_jit_64.S b/arch/powerpc/net/bpf_jit_64.S
> index ff4506e..e590aa5 100644
> --- a/arch/powerpc/net/bpf_jit_64.S
> +++ b/arch/powerpc/net/bpf_jit_64.S
> @@ -31,14 +31,13 @@
>  * then branch directly to slow_path_XXX if required.  (In fact, could
>  * load a spare GPR with the address of slow_path_generic and pass size
>  * as an argument, making the call site a mtlr, li and bllr.)
> - *
> - * Technically, the "is addr < 0" check is unnecessary & slowing down
> - * the ABS path, as it's statically checked on generation.
>  */
>    .globl    sk_load_word
> sk_load_word:
>    cmpdi    r_addr, 0
> -    blt    bpf_error
> +    blt    bpf_slow_path_word_neg
> +    .globl    sk_load_word_positive_offset
> +sk_load_word_positive_offset:
>    /* Are we accessing past headlen? */
>    subi    r_scratch1, r_HL, 4
>    cmpd    r_scratch1, r_addr
> @@ -51,7 +50,9 @@ sk_load_word:
>    .globl    sk_load_half
> sk_load_half:
>    cmpdi    r_addr, 0
> -    blt    bpf_error
> +    blt    bpf_slow_path_half_neg
> +    .globl    sk_load_half_positive_offset
> +sk_load_half_positive_offset:
>    subi    r_scratch1, r_HL, 2
>    cmpd    r_scratch1, r_addr
>    blt    bpf_slow_path_half
> @@ -61,7 +62,9 @@ sk_load_half:
>    .globl    sk_load_byte
> sk_load_byte:
>    cmpdi    r_addr, 0
> -    blt    bpf_error
> +    blt    bpf_slow_path_byte_neg
> +    .globl    sk_load_byte_positive_offset
> +sk_load_byte_positive_offset:
>    cmpd    r_HL, r_addr
>    ble    bpf_slow_path_byte
>    lbzx    r_A, r_D, r_addr
> @@ -69,22 +72,20 @@ sk_load_byte:
> 
> /*
>  * BPF_S_LDX_B_MSH: ldxb  4*([offset]&0xf)
> - * r_addr is the offset value, already known positive
> + * r_addr is the offset value
>  */
>    .globl sk_load_byte_msh
> sk_load_byte_msh:
> +    cmpdi    r_addr, 0
> +    blt    bpf_slow_path_byte_msh_neg
> +    .globl sk_load_byte_msh_positive_offset
> +sk_load_byte_msh_positive_offset:
>    cmpd    r_HL, r_addr
>    ble    bpf_slow_path_byte_msh
>    lbzx    r_X, r_D, r_addr
>    rlwinm    r_X, r_X, 2, 32-4-2, 31-2
>    blr
> 
> -bpf_error:
> -    /* Entered with cr0 = lt */
> -    li    r3, 0
> -    /* Generated code will 'blt epilogue', returning 0. */
> -    blr
> -
> /* Call out to skb_copy_bits:
>  * We'll need to back up our volatile regs first; we have
>  * local variable space at r1+(BPF_PPC_STACK_BASIC).
> @@ -136,3 +137,85 @@ bpf_slow_path_byte_msh:
>    lbz    r_X, BPF_PPC_STACK_BASIC+(2*8)(r1)
>    rlwinm    r_X, r_X, 2, 32-4-2, 31-2
>    blr
> +
> +/* Call out to bpf_internal_load_pointer_neg_helper:
> + * We'll need to back up our volatile regs first; we have
> + * local variable space at r1+(BPF_PPC_STACK_BASIC).
> + * Allocate a new stack frame here to remain ABI-compliant in
> + * stashing LR.
> + */
> +#define sk_negative_common(SIZE)                \
> +    mflr    r0;                        \
> +    std    r0, 16(r1);                    \
> +    /* R3 goes in parameter space of caller's frame */    \
> +    std    r_skb, (BPF_PPC_STACKFRAME+48)(r1);        \
> +    std    r_A, (BPF_PPC_STACK_BASIC+(0*8))(r1);        \
> +    std    r_X, (BPF_PPC_STACK_BASIC+(1*8))(r1);        \
> +    stdu    r1, -BPF_PPC_SLOWPATH_FRAME(r1);        \
> +    /* R3 = r_skb, as passed */                \
> +    mr    r4, r_addr;                    \
> +    li    r5, SIZE;                    \
> +    bl    bpf_internal_load_pointer_neg_helper;        \
> +    /* R3 != 0 on success */                \
> +    addi    r1, r1, BPF_PPC_SLOWPATH_FRAME;            \
> +    ld    r0, 16(r1);                    \
> +    ld    r_A, (BPF_PPC_STACK_BASIC+(0*8))(r1);        \
> +    ld    r_X, (BPF_PPC_STACK_BASIC+(1*8))(r1);        \
> +    mtlr    r0;                        \
> +    cmpldi    r3, 0;                        \
> +    beq    bpf_error_slow;    /* cr0 = EQ */            \
> +    mr    r_addr, r3;                    \
> +    ld    r_skb, (BPF_PPC_STACKFRAME+48)(r1);        \
> +    /* Great success! */
> +
> +bpf_slow_path_word_neg:
> +    lis     r_scratch1,-32    /* SKF_LL_OFF */
> +    cmpd    r_addr, r_scratch1    /* addr < SKF_* */
> +    blt    bpf_error    /* cr0 = LT */
> +    .globl    sk_load_word_negative_offset
> +sk_load_word_negative_offset:
> +    sk_negative_common(4)
> +    lwz    r_A, 0(r_addr)
> +    blr
> +
> +bpf_slow_path_half_neg:
> +    lis     r_scratch1,-32    /* SKF_LL_OFF */
> +    cmpd    r_addr, r_scratch1    /* addr < SKF_* */
> +    blt    bpf_error    /* cr0 = LT */
> +    .globl    sk_load_half_negative_offset
> +sk_load_half_negative_offset:
> +    sk_negative_common(2)
> +    lhz    r_A, 0(r_addr)
> +    blr
> +
> +bpf_slow_path_byte_neg:
> +    lis     r_scratch1,-32    /* SKF_LL_OFF */
> +    cmpd    r_addr, r_scratch1    /* addr < SKF_* */
> +    blt    bpf_error    /* cr0 = LT */
> +    .globl    sk_load_byte_negative_offset
> +sk_load_byte_negative_offset:
> +    sk_negative_common(1)
> +    lbz    r_A, 0(r_addr)
> +    blr
> +
> +bpf_slow_path_byte_msh_neg:
> +    lis     r_scratch1,-32    /* SKF_LL_OFF */
> +    cmpd    r_addr, r_scratch1    /* addr < SKF_* */
> +    blt    bpf_error    /* cr0 = LT */
> +    .globl    sk_load_byte_msh_negative_offset
> +sk_load_byte_msh_negative_offset:
> +    sk_negative_common(1)
> +    lbz    r_X, 0(r_addr)
> +    rlwinm    r_X, r_X, 2, 32-4-2, 31-2
> +    blr
> +
> +bpf_error_slow:
> +    /* fabricate a cr0 = lt */
> +    li    r_scratch1, -1
> +    cmpdi    r_scratch1, 0
> +bpf_error:
> +    /* Entered with cr0 = lt */
> +    li    r3, 0
> +    /* Generated code will 'blt epilogue', returning 0. */
> +    blr
> +
> diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c
> index 73619d3..2dc8b14 100644
> --- a/arch/powerpc/net/bpf_jit_comp.c
> +++ b/arch/powerpc/net/bpf_jit_comp.c
> @@ -127,6 +127,9 @@ static void bpf_jit_build_epilogue(u32 *image, struct codegen_context *ctx)
>    PPC_BLR();
> }
> 
> +#define CHOOSE_LOAD_FUNC(K, func) \
> +    ((int)K < 0 ? ((int)K >= SKF_LL_OFF ? func##_negative_offset : func) : func##_positive_offset)
> +
> /* Assemble the body code between the prologue & epilogue. */
> static int bpf_jit_build_body(struct sk_filter *fp, u32 *image,
>                  struct codegen_context *ctx,
> @@ -391,21 +394,16 @@ static int bpf_jit_build_body(struct sk_filter *fp, u32 *image,
> 
>            /*** Absolute loads from packet header/data ***/
>        case BPF_S_LD_W_ABS:
> -            func = sk_load_word;
> +            func = CHOOSE_LOAD_FUNC(K, sk_load_word);
>            goto common_load;
>        case BPF_S_LD_H_ABS:
> -            func = sk_load_half;
> +            func = CHOOSE_LOAD_FUNC(K, sk_load_half);
>            goto common_load;
>        case BPF_S_LD_B_ABS:
> -            func = sk_load_byte;
> +            func = CHOOSE_LOAD_FUNC(K, sk_load_byte);
>        common_load:
> -            /*
> -             * Load from [K].  Reference with the (negative)
> -             * SKF_NET_OFF/SKF_LL_OFF offsets is unsupported.
> -             */
> +            /* Load from [K]. */
>            ctx->seen |= SEEN_DATAREF;
> -            if ((int)K < 0)
> -                return -ENOTSUPP;
>            PPC_LI64(r_scratch1, func);
>            PPC_MTLR(r_scratch1);
>            PPC_LI32(r_addr, K);
> @@ -429,7 +427,7 @@ static int bpf_jit_build_body(struct sk_filter *fp, u32 *image,
>        common_load_ind:
>            /*
>             * Load from [X + K].  Negative offsets are tested for
> -             * in the helper functions, and result in a 'ret 0'.
> +             * in the helper functions.
>             */
>            ctx->seen |= SEEN_DATAREF | SEEN_XREG;
>            PPC_LI64(r_scratch1, func);
> @@ -443,13 +441,7 @@ static int bpf_jit_build_body(struct sk_filter *fp, u32 *image,
>            break;
> 
>        case BPF_S_LDX_B_MSH:
> -            /*
> -             * x86 version drops packet (RET 0) when K<0, whereas
> -             * interpreter does allow K<0 (__load_pointer, special
> -             * ancillary data).  common_load returns ENOTSUPP if K<0,
> -             * so we fall back to interpreter & filter works.
> -             */
> -            func = sk_load_byte_msh;
> +            func = CHOOSE_LOAD_FUNC(K, sk_load_byte_msh);
>            goto common_load;
>            break;
> 
> diff --git a/arch/x86/net/bpf_jit.S b/arch/x86/net/bpf_jit.S
> index 6687022..2897d7f 100644
> --- a/arch/x86/net/bpf_jit.S
> +++ b/arch/x86/net/bpf_jit.S
> @@ -18,17 +18,17 @@
>  * r9d : hlen = skb->len - skb->data_len
>  */
> #define SKBDATA    %r8
> -
> -sk_load_word_ind:
> -    .globl    sk_load_word_ind
> -
> -    add    %ebx,%esi    /* offset += X */
> -#    test    %esi,%esi    /* if (offset < 0) goto bpf_error; */
> -    js    bpf_error
> +#define SKF_MAX_NEG_OFF    $(-0x200000) /* SKF_LL_OFF from filter.h */
> 
> sk_load_word:
>    .globl    sk_load_word
> 
> +    test    %esi,%esi
> +    js    bpf_slow_path_word_neg
> +
> +sk_load_word_positive_offset:
> +    .globl    sk_load_word_positive_offset
> +
>    mov    %r9d,%eax        # hlen
>    sub    %esi,%eax        # hlen - offset
>    cmp    $3,%eax
> @@ -37,16 +37,15 @@ sk_load_word:
>    bswap   %eax              /* ntohl() */
>    ret
> 
> -
> -sk_load_half_ind:
> -    .globl sk_load_half_ind
> -
> -    add    %ebx,%esi    /* offset += X */
> -    js    bpf_error
> -
> sk_load_half:
>    .globl    sk_load_half
> 
> +    test    %esi,%esi
> +    js    bpf_slow_path_half_neg
> +
> +sk_load_half_positive_offset:
> +    .globl    sk_load_half_positive_offset
> +
>    mov    %r9d,%eax
>    sub    %esi,%eax        #    hlen - offset
>    cmp    $1,%eax
> @@ -55,14 +54,15 @@ sk_load_half:
>    rol    $8,%ax            # ntohs()
>    ret
> 
> -sk_load_byte_ind:
> -    .globl sk_load_byte_ind
> -    add    %ebx,%esi    /* offset += X */
> -    js    bpf_error
> -
> sk_load_byte:
>    .globl    sk_load_byte
> 
> +    test    %esi,%esi
> +    js    bpf_slow_path_byte_neg
> +
> +sk_load_byte_positive_offset:
> +    .globl    sk_load_byte_positive_offset
> +
>    cmp    %esi,%r9d   /* if (offset >= hlen) goto bpf_slow_path_byte */
>    jle    bpf_slow_path_byte
>    movzbl    (SKBDATA,%rsi),%eax
> @@ -73,25 +73,21 @@ sk_load_byte:
>  *
>  * Implements BPF_S_LDX_B_MSH : ldxb  4*([offset]&0xf)
>  * Must preserve A accumulator (%eax)
> - * Inputs : %esi is the offset value, already known positive
> + * Inputs : %esi is the offset value
>  */
> -ENTRY(sk_load_byte_msh)
> -    CFI_STARTPROC
> +sk_load_byte_msh:
> +    .globl    sk_load_byte_msh
> +    test    %esi,%esi
> +    js    bpf_slow_path_byte_msh_neg
> +
> +sk_load_byte_msh_positive_offset:
> +    .globl    sk_load_byte_msh_positive_offset
>    cmp    %esi,%r9d      /* if (offset >= hlen) goto bpf_slow_path_byte_msh */
>    jle    bpf_slow_path_byte_msh
>    movzbl    (SKBDATA,%rsi),%ebx
>    and    $15,%bl
>    shl    $2,%bl
>    ret
> -    CFI_ENDPROC
> -ENDPROC(sk_load_byte_msh)
> -
> -bpf_error:
> -# force a return 0 from jit handler
> -    xor        %eax,%eax
> -    mov        -8(%rbp),%rbx
> -    leaveq
> -    ret
> 
> /* rsi contains offset and can be scratched */
> #define bpf_slow_path_common(LEN)        \
> @@ -138,3 +134,68 @@ bpf_slow_path_byte_msh:
>    shl    $2,%al
>    xchg    %eax,%ebx
>    ret
> +
> +#define sk_negative_common(SIZE)                \
> +    push    %rdi;    /* save skb */                \
> +    push    %r9;                        \
> +    push    SKBDATA;                    \
> +/* rsi already has offset */                    \
> +    mov    $SIZE,%ecx;    /* size */            \
> +    call    bpf_internal_load_pointer_neg_helper;        \
> +    test    %rax,%rax;                    \
> +    pop    SKBDATA;                    \
> +    pop    %r9;                        \
> +    pop    %rdi;                        \
> +    jz    bpf_error
> +
> +
> +bpf_slow_path_word_neg:
> +    cmp    SKF_MAX_NEG_OFF, %esi    /* test range */
> +    jl    bpf_error    /* offset lower -> error  */
> +sk_load_word_negative_offset:
> +    .globl    sk_load_word_negative_offset
> +    sk_negative_common(4)
> +    mov    (%rax), %eax
> +    bswap    %eax
> +    ret
> +
> +bpf_slow_path_half_neg:
> +    cmp    SKF_MAX_NEG_OFF, %esi
> +    jl    bpf_error
> +sk_load_half_negative_offset:
> +    .globl    sk_load_half_negative_offset
> +    sk_negative_common(2)
> +    mov    (%rax),%ax
> +    rol    $8,%ax
> +    movzwl    %ax,%eax
> +    ret
> +
> +bpf_slow_path_byte_neg:
> +    cmp    SKF_MAX_NEG_OFF, %esi
> +    jl    bpf_error
> +sk_load_byte_negative_offset:
> +    .globl    sk_load_byte_negative_offset
> +    sk_negative_common(1)
> +    movzbl    (%rax), %eax
> +    ret
> +
> +bpf_slow_path_byte_msh_neg:
> +    cmp    SKF_MAX_NEG_OFF, %esi
> +    jl    bpf_error
> +sk_load_byte_msh_negative_offset:
> +    .globl    sk_load_byte_msh_negative_offset
> +    xchg    %eax,%ebx /* dont lose A , X is about to be scratched */
> +    sk_negative_common(1)
> +    movzbl    (%rax),%eax
> +    and    $15,%al
> +    shl    $2,%al
> +    xchg    %eax,%ebx
> +    ret
> +
> +bpf_error:
> +# force a return 0 from jit handler
> +    xor        %eax,%eax
> +    mov        -8(%rbp),%rbx
> +    leaveq
> +    ret
> +
> diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c
> index 5671752..39a2e2c 100644
> --- a/arch/x86/net/bpf_jit_comp.c
> +++ b/arch/x86/net/bpf_jit_comp.c
> @@ -30,7 +30,10 @@ int bpf_jit_enable __read_mostly;
>  * assembly code in arch/x86/net/bpf_jit.S
>  */
> extern u8 sk_load_word[], sk_load_half[], sk_load_byte[], sk_load_byte_msh[];
> -extern u8 sk_load_word_ind[], sk_load_half_ind[], sk_load_byte_ind[];
> +extern u8 sk_load_word_positive_offset[], sk_load_half_positive_offset[];
> +extern u8 sk_load_byte_positive_offset[], sk_load_byte_msh_positive_offset[];
> +extern u8 sk_load_word_negative_offset[], sk_load_half_negative_offset[];
> +extern u8 sk_load_byte_negative_offset[], sk_load_byte_msh_negative_offset[];
> 
> static inline u8 *emit_code(u8 *ptr, u32 bytes, unsigned int len)
> {
> @@ -117,6 +120,8 @@ static inline void bpf_flush_icache(void *start, void *end)
>    set_fs(old_fs);
> }
> 
> +#define CHOOSE_LOAD_FUNC(K, func) \
> +    ((int)K < 0 ? ((int)K >= SKF_LL_OFF ? func##_negative_offset : func) : func##_positive_offset)
> 
> void bpf_jit_compile(struct sk_filter *fp)
> {
> @@ -473,44 +478,46 @@ void bpf_jit_compile(struct sk_filter *fp)
> #endif
>                break;
>            case BPF_S_LD_W_ABS:
> -                func = sk_load_word;
> +                func = CHOOSE_LOAD_FUNC(K, sk_load_word);
> common_load:            seen |= SEEN_DATAREF;
> -                if ((int)K < 0) {
> -                    /* Abort the JIT because __load_pointer() is needed. */
> -                    goto out;
> -                }
>                t_offset = func - (image + addrs[i]);
>                EMIT1_off32(0xbe, K); /* mov imm32,%esi */
>                EMIT1_off32(0xe8, t_offset); /* call */
>                break;
>            case BPF_S_LD_H_ABS:
> -                func = sk_load_half;
> +                func = CHOOSE_LOAD_FUNC(K, sk_load_half);
>                goto common_load;
>            case BPF_S_LD_B_ABS:
> -                func = sk_load_byte;
> +                func = CHOOSE_LOAD_FUNC(K, sk_load_byte);
>                goto common_load;
>            case BPF_S_LDX_B_MSH:
> -                if ((int)K < 0) {
> -                    /* Abort the JIT because __load_pointer() is needed. */
> -                    goto out;
> -                }
> +                func = CHOOSE_LOAD_FUNC(K, sk_load_byte_msh);
>                seen |= SEEN_DATAREF | SEEN_XREG;
> -                t_offset = sk_load_byte_msh - (image + addrs[i]);
> +                t_offset = func - (image + addrs[i]);
>                EMIT1_off32(0xbe, K);    /* mov imm32,%esi */
>                EMIT1_off32(0xe8, t_offset); /* call sk_load_byte_msh */
>                break;
>            case BPF_S_LD_W_IND:
> -                func = sk_load_word_ind;
> +                func = sk_load_word;
> common_load_ind:        seen |= SEEN_DATAREF | SEEN_XREG;
>                t_offset = func - (image + addrs[i]);
> -                EMIT1_off32(0xbe, K);    /* mov imm32,%esi   */
> +                if (K) {
> +                    if (is_imm8(K)) {
> +                        EMIT3(0x8d, 0x73, K); /* lea imm8(%rbx), %esi */
> +                    } else {
> +                        EMIT2(0x8d, 0xb3); /* lea imm32(%rbx),%esi */
> +                        EMIT(K, 4);
> +                    }
> +                } else {
> +                    EMIT2(0x89,0xde); /* mov %ebx,%esi */
> +                }
>                EMIT1_off32(0xe8, t_offset);    /* call sk_load_xxx_ind */
>                break;
>            case BPF_S_LD_H_IND:
> -                func = sk_load_half_ind;
> +                func = sk_load_half;
>                goto common_load_ind;
>            case BPF_S_LD_B_IND:
> -                func = sk_load_byte_ind;
> +                func = sk_load_byte;
>                goto common_load_ind;
>            case BPF_S_JMP_JA:
>                t_offset = addrs[i + K] - addrs[i];
> diff --git a/net/core/filter.c b/net/core/filter.c
> index 5dea452..04ca613 100644
> --- a/net/core/filter.c
> +++ b/net/core/filter.c
> @@ -41,7 +41,7 @@
> #include <linux/ratelimit.h>
> 
> /* No hurry in this branch */
> -static void *__load_pointer(const struct sk_buff *skb, int k, unsigned int size)
> +void *bpf_internal_load_pointer_neg_helper(const struct sk_buff *skb, int k, unsigned int size)
> {
>    u8 *ptr = NULL;
> 
> @@ -54,13 +54,14 @@ static void *__load_pointer(const struct sk_buff *skb, int k, unsigned int size)
>        return ptr;
>    return NULL;
> }
> +EXPORT_SYMBOL(bpf_internal_load_pointer_neg_helper);
> 
> static inline void *load_pointer(const struct sk_buff *skb, int k,
>                 unsigned int size, void *buffer)
> {
>    if (k >= 0)
>        return skb_header_pointer(skb, k, size, buffer);
> -    return __load_pointer(skb, k, size);
> +    return bpf_internal_load_pointer_neg_helper(skb, k, size);
> }
> 
> /**
> 

^ permalink raw reply

* Re: [PATCH 05/12] Add dummy smsc911x regulators to cm-t35.
From: Igor Grinberg @ 2012-03-30 15:23 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Russ Dill, linux-omap, Mark Brown, Matt Porter, robert.marklund,
	linus.walleij, linux-arm-kernel, netdev@vger.kernel.org
In-Reply-To: <20120328170316.GR9859@atomide.com>

On 03/28/12 19:03, Tony Lindgren wrote:
> * Igor Grinberg <grinberg@compulab.co.il> [120327 23:36]:
>> Hi Tony,
>>
>> On 03/27/12 19:28, Tony Lindgren wrote:
>>> * Igor Grinberg <grinberg@compulab.co.il> [120327 08:56]:
>>>> Hi Russ,
>>>>
>>>> This patch works, but can we, please use the attached patch instead?
>>>
>>> Hmm what's the difference here? Do you have some real controllable
>>> regulator for one of the smsc911x instances?
>>
>> Well, the difference here is that those regulators will only be present
>> if the smsc911x controllers are present and their initialization is done
>> along with the controllers.
>> Also, I want to separate the cm-t35 from sb-t35 for future easier
>> refactoring of the sb-t35 code so it can be reused also on cm-t3517.
>>
>> Only vddvario for smsc911x.0 is controllable - connected to VIO, but
>> VIO will never be disabled as it also controls many other devices
>> (DRAM is among them), so I prefer it to be dummy and keep it together
>> with vdd33a.
> 
> OK thanks for the clarification. 
> 
>>> Anyways, I take it that you have tested that both smsc911x interfaces
>>> work now?
>>
>> Yes, both regulators are registered and found by the smsc911x driver.
>> There is some kind of problem with the smsc911x.1, but it looks unrelated
>> to the patch:
> 
> OK good to hear. Regarding the following problem..
>  
>> smsc911x: Driver version 2008-10-21
>> irq 323: nobody cared (try booting with the "irqpoll" option)
>> [<c001ae6c>] (unwind_backtrace+0x0/0xfc) from [<c0088960>] (__report_bad_irq+0x28/0xbc)
>> [<c0088960>] (__report_bad_irq+0x28/0xbc) from [<c0088bd4>] (note_interrupt+0x1e0/0x230)
>> [<c0088bd4>] (note_interrupt+0x1e0/0x230) from [<c0086e48>] (handle_irq_event_percpu+0xb0/0x1a0)
>> [<c0086e48>] (handle_irq_event_percpu+0xb0/0x1a0) from [<c0086f74>] (handle_irq_event+0x3c/0x5c)
>> [<c0086f74>] (handle_irq_event+0x3c/0x5c) from [<c00895a0>] (handle_level_irq+0x90/0xfc)
>> [<c00895a0>] (handle_level_irq+0x90/0xfc) from [<c008699c>] (generic_handle_irq+0x38/0x40)
>> [<c008699c>] (generic_handle_irq+0x38/0x40) from [<c02635a0>] (gpio_irq_handler+0x1b0/0x20c)
>> [<c02635a0>] (gpio_irq_handler+0x1b0/0x20c) from [<c008699c>] (generic_handle_irq+0x38/0x40)
>> [<c008699c>] (generic_handle_irq+0x38/0x40) from [<c0015404>] (handle_IRQ+0x38/0x84)
>> [<c0015404>] (handle_IRQ+0x38/0x84) from [<c000865c>] (omap3_intc_handle_irq+0x48/0x4c)
>> [<c000865c>] (omap3_intc_handle_irq+0x48/0x4c) from [<c00140c4>] (__irq_svc+0x44/0x78)
>> Exception stack(0xcf02de20 to 0xcf02de68)
>> de20: cf02c018 cf02c000 00000000 cf02de58 60000013 c06739fc 00000143 c06739fc
>> de40: 60000013 00000508 c06739dc 00000000 00022d69 cf02de68 cf02b3c0 c04890fc
>> de60: 20000013 ffffffff
>> [<c00140c4>] (__irq_svc+0x44/0x78) from [<c04890fc>] (_raw_spin_unlock_irqrestore+0x64/0x68)
>> [<c04890fc>] (_raw_spin_unlock_irqrestore+0x64/0x68) from [<c0087d50>] (__setup_irq+0x1b4/0x3d4)
>> [<c0087d50>] (__setup_irq+0x1b4/0x3d4) from [<c00881a0>] (request_threaded_irq+0xdc/0x148)
>> [<c00881a0>] (request_threaded_irq+0xdc/0x148) from [<c0482954>] (smsc911x_drv_probe+0x350/0x528)
>> [<c0482954>] (smsc911x_drv_probe+0x350/0x528) from [<c02d5a8c>] (platform_drv_probe+0x18/0x1c)
>> [<c02d5a8c>] (platform_drv_probe+0x18/0x1c) from [<c02d4580>] (really_probe+0x64/0x160)
>> [<c02d4580>] (really_probe+0x64/0x160) from [<c02d46c4>] (driver_probe_device+0x48/0x60)
>> [<c02d46c4>] (driver_probe_device+0x48/0x60) from [<c02d4770>] (__driver_attach+0x94/0x98)
>> [<c02d4770>] (__driver_attach+0x94/0x98) from [<c02d2ffc>] (bus_for_each_dev+0x54/0x80)
>> [<c02d2ffc>] (bus_for_each_dev+0x54/0x80) from [<c02d3730>] (bus_add_driver+0xa8/0x2a4)
>> [<c02d3730>] (bus_add_driver+0xa8/0x2a4) from [<c02d4d6c>] (driver_register+0x78/0x184)
>> [<c02d4d6c>] (driver_register+0x78/0x184) from [<c0008758>] (do_one_initcall+0x34/0x184)
>> [<c0008758>] (do_one_initcall+0x34/0x184) from [<c0613248>] (do_basic_setup+0x34/0x40)
>> [<c0613248>] (do_basic_setup+0x34/0x40) from [<c06132b8>] (kernel_init+0x64/0xec)
>> [<c06132b8>] (kernel_init+0x64/0xec) from [<c00154cc>] (kernel_thread_exit+0x0/0x8)
>> handlers:
>> [<c032ea98>] smsc911x_irqhandler
>> Disabling IRQ #323
>>
>> I still haven't had a chance to look into this.
>> Does anyone have a clue?
> 
> ..care to see if you have OMAP_GPIO_IRQ entry for your board? If so, we're
> still waiting for the cleanup-fixes branch to get merged that changes
> things to use gpio_to_irq() instead.

Nope, no OMAP_GPIO_IRQ in the board code.
Also, the GPIO -> IRQ mapping for the smsc911x is done in gpmc-smsc911x.c
and it uses gpio_to_irq() already.


-- 
Regards,
Igor.

^ permalink raw reply

* [REGRESSION][PATCH V4 2/3] bpf jit: Let the x86 jit handle negative offsets
From: Jan Seiffert @ 2012-03-30 15:24 UTC (permalink / raw)
  To: netdev; +Cc: linux-kernel, Eric Dumazet, David S. Miller
In-Reply-To: <4F75CA89.4010709@googlemail.com>

Now the helper function from filter.c for negative offsets is exported,
it can be used it in the jit to handle negative offsets.

First modify the asm load helper functions to handle:
- know positive offsets
- know negative offsets
- any offset

then the compiler can be modified to explicitly use these helper
when appropriate.

This fixes the case of a negative X register and allows to lift
the restriction that bpf programs with negative offsets can't
be jited.

Signed-of-by: Jan Seiffert <kaffeemonster@googlemail.com>

diff --git a/arch/x86/net/bpf_jit.S b/arch/x86/net/bpf_jit.S
index 6687022..2897d7f 100644
--- a/arch/x86/net/bpf_jit.S
+++ b/arch/x86/net/bpf_jit.S
@@ -18,17 +18,17 @@
  * r9d : hlen = skb->len - skb->data_len
  */
 #define SKBDATA	%r8
-
-sk_load_word_ind:
-	.globl	sk_load_word_ind
-
-	add	%ebx,%esi	/* offset += X */
-#	test    %esi,%esi	/* if (offset < 0) goto bpf_error; */
-	js	bpf_error
+#define SKF_MAX_NEG_OFF    $(-0x200000) /* SKF_LL_OFF from filter.h */
 
 sk_load_word:
 	.globl	sk_load_word
 
+	test	%esi,%esi
+	js	bpf_slow_path_word_neg
+
+sk_load_word_positive_offset:
+	.globl	sk_load_word_positive_offset
+
 	mov	%r9d,%eax		# hlen
 	sub	%esi,%eax		# hlen - offset
 	cmp	$3,%eax
@@ -37,16 +37,15 @@ sk_load_word:
 	bswap   %eax  			/* ntohl() */
 	ret
 
-
-sk_load_half_ind:
-	.globl sk_load_half_ind
-
-	add	%ebx,%esi	/* offset += X */
-	js	bpf_error
-
 sk_load_half:
 	.globl	sk_load_half
 
+	test	%esi,%esi
+	js	bpf_slow_path_half_neg
+
+sk_load_half_positive_offset:
+	.globl	sk_load_half_positive_offset
+
 	mov	%r9d,%eax
 	sub	%esi,%eax		#	hlen - offset
 	cmp	$1,%eax
@@ -55,14 +54,15 @@ sk_load_half:
 	rol	$8,%ax			# ntohs()
 	ret
 
-sk_load_byte_ind:
-	.globl sk_load_byte_ind
-	add	%ebx,%esi	/* offset += X */
-	js	bpf_error
-
 sk_load_byte:
 	.globl	sk_load_byte
 
+	test	%esi,%esi
+	js	bpf_slow_path_byte_neg
+
+sk_load_byte_positive_offset:
+	.globl	sk_load_byte_positive_offset
+
 	cmp	%esi,%r9d   /* if (offset >= hlen) goto bpf_slow_path_byte */
 	jle	bpf_slow_path_byte
 	movzbl	(SKBDATA,%rsi),%eax
@@ -73,25 +73,21 @@ sk_load_byte:
  *
  * Implements BPF_S_LDX_B_MSH : ldxb  4*([offset]&0xf)
  * Must preserve A accumulator (%eax)
- * Inputs : %esi is the offset value, already known positive
+ * Inputs : %esi is the offset value
  */
-ENTRY(sk_load_byte_msh)
-	CFI_STARTPROC
+sk_load_byte_msh:
+	.globl	sk_load_byte_msh
+	test	%esi,%esi
+	js	bpf_slow_path_byte_msh_neg
+
+sk_load_byte_msh_positive_offset:
+	.globl	sk_load_byte_msh_positive_offset
 	cmp	%esi,%r9d      /* if (offset >= hlen) goto bpf_slow_path_byte_msh */
 	jle	bpf_slow_path_byte_msh
 	movzbl	(SKBDATA,%rsi),%ebx
 	and	$15,%bl
 	shl	$2,%bl
 	ret
-	CFI_ENDPROC
-ENDPROC(sk_load_byte_msh)
-
-bpf_error:
-# force a return 0 from jit handler
-	xor		%eax,%eax
-	mov		-8(%rbp),%rbx
-	leaveq
-	ret
 
 /* rsi contains offset and can be scratched */
 #define bpf_slow_path_common(LEN)		\
@@ -138,3 +134,68 @@ bpf_slow_path_byte_msh:
 	shl	$2,%al
 	xchg	%eax,%ebx
 	ret
+
+#define sk_negative_common(SIZE)				\
+	push	%rdi;	/* save skb */				\
+	push	%r9;						\
+	push	SKBDATA;					\
+/* rsi already has offset */					\
+	mov	$SIZE,%ecx;	/* size */			\
+	call	bpf_internal_load_pointer_neg_helper;		\
+	test	%rax,%rax;					\
+	pop	SKBDATA;					\
+	pop	%r9;						\
+	pop	%rdi;						\
+	jz	bpf_error
+
+
+bpf_slow_path_word_neg:
+	cmp	SKF_MAX_NEG_OFF, %esi	/* test range */
+	jl	bpf_error	/* offset lower -> error  */
+sk_load_word_negative_offset:
+	.globl	sk_load_word_negative_offset
+	sk_negative_common(4)
+	mov	(%rax), %eax
+	bswap	%eax
+	ret
+
+bpf_slow_path_half_neg:
+	cmp	SKF_MAX_NEG_OFF, %esi
+	jl	bpf_error
+sk_load_half_negative_offset:
+	.globl	sk_load_half_negative_offset
+	sk_negative_common(2)
+	mov	(%rax),%ax
+	rol	$8,%ax
+	movzwl	%ax,%eax
+	ret
+
+bpf_slow_path_byte_neg:
+	cmp	SKF_MAX_NEG_OFF, %esi
+	jl	bpf_error
+sk_load_byte_negative_offset:
+	.globl	sk_load_byte_negative_offset
+	sk_negative_common(1)
+	movzbl	(%rax), %eax
+	ret
+
+bpf_slow_path_byte_msh_neg:
+	cmp	SKF_MAX_NEG_OFF, %esi
+	jl	bpf_error
+sk_load_byte_msh_negative_offset:
+	.globl	sk_load_byte_msh_negative_offset
+	xchg	%eax,%ebx /* dont lose A , X is about to be scratched */
+	sk_negative_common(1)
+	movzbl	(%rax),%eax
+	and	$15,%al
+	shl	$2,%al
+	xchg	%eax,%ebx
+	ret
+
+bpf_error:
+# force a return 0 from jit handler
+	xor		%eax,%eax
+	mov		-8(%rbp),%rbx
+	leaveq
+	ret
+
diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c
index 5671752..39a2e2c 100644
--- a/arch/x86/net/bpf_jit_comp.c
+++ b/arch/x86/net/bpf_jit_comp.c
@@ -30,7 +30,10 @@ int bpf_jit_enable __read_mostly;
  * assembly code in arch/x86/net/bpf_jit.S
  */
 extern u8 sk_load_word[], sk_load_half[], sk_load_byte[], sk_load_byte_msh[];
-extern u8 sk_load_word_ind[], sk_load_half_ind[], sk_load_byte_ind[];
+extern u8 sk_load_word_positive_offset[], sk_load_half_positive_offset[];
+extern u8 sk_load_byte_positive_offset[], sk_load_byte_msh_positive_offset[];
+extern u8 sk_load_word_negative_offset[], sk_load_half_negative_offset[];
+extern u8 sk_load_byte_negative_offset[], sk_load_byte_msh_negative_offset[];
 
 static inline u8 *emit_code(u8 *ptr, u32 bytes, unsigned int len)
 {
@@ -117,6 +120,8 @@ static inline void bpf_flush_icache(void *start, void *end)
 	set_fs(old_fs);
 }
 
+#define CHOOSE_LOAD_FUNC(K, func) \
+	((int)K < 0 ? ((int)K >= SKF_LL_OFF ? func##_negative_offset : func) : func##_positive_offset)
 
 void bpf_jit_compile(struct sk_filter *fp)
 {
@@ -473,44 +478,46 @@ void bpf_jit_compile(struct sk_filter *fp)
 #endif
 				break;
 			case BPF_S_LD_W_ABS:
-				func = sk_load_word;
+				func = CHOOSE_LOAD_FUNC(K, sk_load_word);
 common_load:			seen |= SEEN_DATAREF;
-				if ((int)K < 0) {
-					/* Abort the JIT because __load_pointer() is needed. */
-					goto out;
-				}
 				t_offset = func - (image + addrs[i]);
 				EMIT1_off32(0xbe, K); /* mov imm32,%esi */
 				EMIT1_off32(0xe8, t_offset); /* call */
 				break;
 			case BPF_S_LD_H_ABS:
-				func = sk_load_half;
+				func = CHOOSE_LOAD_FUNC(K, sk_load_half);
 				goto common_load;
 			case BPF_S_LD_B_ABS:
-				func = sk_load_byte;
+				func = CHOOSE_LOAD_FUNC(K, sk_load_byte);
 				goto common_load;
 			case BPF_S_LDX_B_MSH:
-				if ((int)K < 0) {
-					/* Abort the JIT because __load_pointer() is needed. */
-					goto out;
-				}
+				func = CHOOSE_LOAD_FUNC(K, sk_load_byte_msh);
 				seen |= SEEN_DATAREF | SEEN_XREG;
-				t_offset = sk_load_byte_msh - (image + addrs[i]);
+				t_offset = func - (image + addrs[i]);
 				EMIT1_off32(0xbe, K);	/* mov imm32,%esi */
 				EMIT1_off32(0xe8, t_offset); /* call sk_load_byte_msh */
 				break;
 			case BPF_S_LD_W_IND:
-				func = sk_load_word_ind;
+				func = sk_load_word;
 common_load_ind:		seen |= SEEN_DATAREF | SEEN_XREG;
 				t_offset = func - (image + addrs[i]);
-				EMIT1_off32(0xbe, K);	/* mov imm32,%esi   */
+				if (K) {
+					if (is_imm8(K)) {
+						EMIT3(0x8d, 0x73, K); /* lea imm8(%rbx), %esi */
+					} else {
+						EMIT2(0x8d, 0xb3); /* lea imm32(%rbx),%esi */
+						EMIT(K, 4);
+					}
+				} else {
+					EMIT2(0x89,0xde); /* mov %ebx,%esi */
+				}
 				EMIT1_off32(0xe8, t_offset);	/* call sk_load_xxx_ind */
 				break;
 			case BPF_S_LD_H_IND:
-				func = sk_load_half_ind;
+				func = sk_load_half;
 				goto common_load_ind;
 			case BPF_S_LD_B_IND:
-				func = sk_load_byte_ind;
+				func = sk_load_byte;
 				goto common_load_ind;
 			case BPF_S_JMP_JA:
 				t_offset = addrs[i + K] - addrs[i];

^ permalink raw reply related

* Re: [REGRESSION][PATCH] bpf_jit drops the ball on indirect negative mem references
From: Matt Evans @ 2012-03-30 15:24 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: Jan Seiffert, netdev@vger.kernel.org,
	linux-kernel@vger.kernel.org, David S. Miller
In-Reply-To: <1333116493.2325.2125.camel@edumazet-glaptop>

Howdy Eric,

On 30 Mar 2012, at 15:08, Eric Dumazet <eric.dumazet@gmail.com> wrote:

> On Fri, 2012-03-30 at 15:42 +0200, Jan Seiffert wrote:
> 
>> Do you know where i can ping the powerpc guys a little bit harder?
> 
> maybe using CC linux-arch@vger.kernel.org
> 
> One way to handle that would be to split this patch in 3 parts, so that
> I can Ack the non ppc part.
> 
> [1] introduce bpf_internal_load_pointer_neg_helper()
>    [BTW no need to EXPORT_SYMBOL it, since jit is not a module ]
> 
> [2] x86_bpf_iit: handle negative offsets in loads
> 
> [3] ppc_bpf_jit: handle negative offsets in loads

Yeah, that'd be great, then I can stew on it without holding you up further. 

Cheers,

Matt



> 
> 

^ permalink raw reply

* [REGRESSION][PATCH V4 3/3] bpf jit: Let the powerpc jit handle negative offsets
From: Jan Seiffert @ 2012-03-30 15:35 UTC (permalink / raw)
  To: netdev
  Cc: linux-kernel, linuxppc-dev, Matt Evans, Eric Dumazet,
	David S. Miller
In-Reply-To: <4F75CA89.4010709@googlemail.com>

Now the helper function from filter.c for negative offsets is exported,
it can be used it in the jit to handle negative offsets.

First modify the asm load helper functions to handle:
- know positive offsets
- know negative offsets
- any offset

then the compiler can be modified to explicitly use these helper
when appropriate.

This fixes the case of a negative X register and allows to lift
the restriction that bpf programs with negative offsets can't
be jited.

Signed-off-by: Jan Seiffert <kaffeemonster@googlemail.com>

I have only compile tested this, -ENOHARDWARE.
Can someone with more powerpc kung-fu review and maybe test this?
Esp. powerpc asm is not my strong point. I think i botched the
stack frame in the call setup. Help?

diff --git a/arch/powerpc/net/bpf_jit_64.S b/arch/powerpc/net/bpf_jit_64.S
index ff4506e..e590aa5 100644
--- a/arch/powerpc/net/bpf_jit_64.S
+++ b/arch/powerpc/net/bpf_jit_64.S
@@ -31,14 +31,13 @@
  * then branch directly to slow_path_XXX if required.  (In fact, could
  * load a spare GPR with the address of slow_path_generic and pass size
  * as an argument, making the call site a mtlr, li and bllr.)
- *
- * Technically, the "is addr < 0" check is unnecessary & slowing down
- * the ABS path, as it's statically checked on generation.
  */
 	.globl	sk_load_word
 sk_load_word:
 	cmpdi	r_addr, 0
-	blt	bpf_error
+	blt	bpf_slow_path_word_neg
+	.globl	sk_load_word_positive_offset
+sk_load_word_positive_offset:
 	/* Are we accessing past headlen? */
 	subi	r_scratch1, r_HL, 4
 	cmpd	r_scratch1, r_addr
@@ -51,7 +50,9 @@ sk_load_word:
 	.globl	sk_load_half
 sk_load_half:
 	cmpdi	r_addr, 0
-	blt	bpf_error
+	blt	bpf_slow_path_half_neg
+	.globl	sk_load_half_positive_offset
+sk_load_half_positive_offset:
 	subi	r_scratch1, r_HL, 2
 	cmpd	r_scratch1, r_addr
 	blt	bpf_slow_path_half
@@ -61,7 +62,9 @@ sk_load_half:
 	.globl	sk_load_byte
 sk_load_byte:
 	cmpdi	r_addr, 0
-	blt	bpf_error
+	blt	bpf_slow_path_byte_neg
+	.globl	sk_load_byte_positive_offset
+sk_load_byte_positive_offset:
 	cmpd	r_HL, r_addr
 	ble	bpf_slow_path_byte
 	lbzx	r_A, r_D, r_addr
@@ -69,22 +72,20 @@ sk_load_byte:
 
 /*
  * BPF_S_LDX_B_MSH: ldxb  4*([offset]&0xf)
- * r_addr is the offset value, already known positive
+ * r_addr is the offset value
  */
 	.globl sk_load_byte_msh
 sk_load_byte_msh:
+	cmpdi	r_addr, 0
+	blt	bpf_slow_path_byte_msh_neg
+	.globl sk_load_byte_msh_positive_offset
+sk_load_byte_msh_positive_offset:
 	cmpd	r_HL, r_addr
 	ble	bpf_slow_path_byte_msh
 	lbzx	r_X, r_D, r_addr
 	rlwinm	r_X, r_X, 2, 32-4-2, 31-2
 	blr
 
-bpf_error:
-	/* Entered with cr0 = lt */
-	li	r3, 0
-	/* Generated code will 'blt epilogue', returning 0. */
-	blr
-
 /* Call out to skb_copy_bits:
  * We'll need to back up our volatile regs first; we have
  * local variable space at r1+(BPF_PPC_STACK_BASIC).
@@ -136,3 +137,85 @@ bpf_slow_path_byte_msh:
 	lbz	r_X, BPF_PPC_STACK_BASIC+(2*8)(r1)
 	rlwinm	r_X, r_X, 2, 32-4-2, 31-2
 	blr
+
+/* Call out to bpf_internal_load_pointer_neg_helper:
+ * We'll need to back up our volatile regs first; we have
+ * local variable space at r1+(BPF_PPC_STACK_BASIC).
+ * Allocate a new stack frame here to remain ABI-compliant in
+ * stashing LR.
+ */
+#define sk_negative_common(SIZE)				\
+	mflr	r0;						\
+	std	r0, 16(r1);					\
+	/* R3 goes in parameter space of caller's frame */	\
+	std	r_skb, (BPF_PPC_STACKFRAME+48)(r1);		\
+	std	r_A, (BPF_PPC_STACK_BASIC+(0*8))(r1);		\
+	std	r_X, (BPF_PPC_STACK_BASIC+(1*8))(r1);		\
+	stdu	r1, -BPF_PPC_SLOWPATH_FRAME(r1);		\
+	/* R3 = r_skb, as passed */				\
+	mr	r4, r_addr;					\
+	li	r5, SIZE;					\
+	bl	bpf_internal_load_pointer_neg_helper;		\
+	/* R3 != 0 on success */				\
+	addi	r1, r1, BPF_PPC_SLOWPATH_FRAME;			\
+	ld	r0, 16(r1);					\
+	ld	r_A, (BPF_PPC_STACK_BASIC+(0*8))(r1);		\
+	ld	r_X, (BPF_PPC_STACK_BASIC+(1*8))(r1);		\
+	mtlr	r0;						\
+	cmpldi	r3, 0;						\
+	beq	bpf_error_slow;	/* cr0 = EQ */			\
+	mr	r_addr, r3;					\
+	ld	r_skb, (BPF_PPC_STACKFRAME+48)(r1);		\
+	/* Great success! */
+
+bpf_slow_path_word_neg:
+	lis     r_scratch1,-32	/* SKF_LL_OFF */
+	cmpd	r_addr, r_scratch1	/* addr < SKF_* */
+	blt	bpf_error	/* cr0 = LT */
+	.globl	sk_load_word_negative_offset
+sk_load_word_negative_offset:
+	sk_negative_common(4)
+	lwz	r_A, 0(r_addr)
+	blr
+
+bpf_slow_path_half_neg:
+	lis     r_scratch1,-32	/* SKF_LL_OFF */
+	cmpd	r_addr, r_scratch1	/* addr < SKF_* */
+	blt	bpf_error	/* cr0 = LT */
+	.globl	sk_load_half_negative_offset
+sk_load_half_negative_offset:
+	sk_negative_common(2)
+	lhz	r_A, 0(r_addr)
+	blr
+
+bpf_slow_path_byte_neg:
+	lis     r_scratch1,-32	/* SKF_LL_OFF */
+	cmpd	r_addr, r_scratch1	/* addr < SKF_* */
+	blt	bpf_error	/* cr0 = LT */
+	.globl	sk_load_byte_negative_offset
+sk_load_byte_negative_offset:
+	sk_negative_common(1)
+	lbz	r_A, 0(r_addr)
+	blr
+
+bpf_slow_path_byte_msh_neg:
+	lis     r_scratch1,-32	/* SKF_LL_OFF */
+	cmpd	r_addr, r_scratch1	/* addr < SKF_* */
+	blt	bpf_error	/* cr0 = LT */
+	.globl	sk_load_byte_msh_negative_offset
+sk_load_byte_msh_negative_offset:
+	sk_negative_common(1)
+	lbz	r_X, 0(r_addr)
+	rlwinm	r_X, r_X, 2, 32-4-2, 31-2
+	blr
+
+bpf_error_slow:
+	/* fabricate a cr0 = lt */
+	li	r_scratch1, -1
+	cmpdi	r_scratch1, 0
+bpf_error:
+	/* Entered with cr0 = lt */
+	li	r3, 0
+	/* Generated code will 'blt epilogue', returning 0. */
+	blr
+
diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c
index 73619d3..2dc8b14 100644
--- a/arch/powerpc/net/bpf_jit_comp.c
+++ b/arch/powerpc/net/bpf_jit_comp.c
@@ -127,6 +127,9 @@ static void bpf_jit_build_epilogue(u32 *image, struct codegen_context *ctx)
 	PPC_BLR();
 }
 
+#define CHOOSE_LOAD_FUNC(K, func) \
+	((int)K < 0 ? ((int)K >= SKF_LL_OFF ? func##_negative_offset : func) : func##_positive_offset)
+
 /* Assemble the body code between the prologue & epilogue. */
 static int bpf_jit_build_body(struct sk_filter *fp, u32 *image,
 			      struct codegen_context *ctx,
@@ -391,21 +394,16 @@ static int bpf_jit_build_body(struct sk_filter *fp, u32 *image,
 
 			/*** Absolute loads from packet header/data ***/
 		case BPF_S_LD_W_ABS:
-			func = sk_load_word;
+			func = CHOOSE_LOAD_FUNC(K, sk_load_word);
 			goto common_load;
 		case BPF_S_LD_H_ABS:
-			func = sk_load_half;
+			func = CHOOSE_LOAD_FUNC(K, sk_load_half);
 			goto common_load;
 		case BPF_S_LD_B_ABS:
-			func = sk_load_byte;
+			func = CHOOSE_LOAD_FUNC(K, sk_load_byte);
 		common_load:
-			/*
-			 * Load from [K].  Reference with the (negative)
-			 * SKF_NET_OFF/SKF_LL_OFF offsets is unsupported.
-			 */
+			/* Load from [K]. */
 			ctx->seen |= SEEN_DATAREF;
-			if ((int)K < 0)
-				return -ENOTSUPP;
 			PPC_LI64(r_scratch1, func);
 			PPC_MTLR(r_scratch1);
 			PPC_LI32(r_addr, K);
@@ -429,7 +427,7 @@ static int bpf_jit_build_body(struct sk_filter *fp, u32 *image,
 		common_load_ind:
 			/*
 			 * Load from [X + K].  Negative offsets are tested for
-			 * in the helper functions, and result in a 'ret 0'.
+			 * in the helper functions.
 			 */
 			ctx->seen |= SEEN_DATAREF | SEEN_XREG;
 			PPC_LI64(r_scratch1, func);
@@ -443,13 +441,7 @@ static int bpf_jit_build_body(struct sk_filter *fp, u32 *image,
 			break;
 
 		case BPF_S_LDX_B_MSH:
-			/*
-			 * x86 version drops packet (RET 0) when K<0, whereas
-			 * interpreter does allow K<0 (__load_pointer, special
-			 * ancillary data).  common_load returns ENOTSUPP if K<0,
-			 * so we fall back to interpreter & filter works.
-			 */
-			func = sk_load_byte_msh;
+			func = CHOOSE_LOAD_FUNC(K, sk_load_byte_msh);
 			goto common_load;
 			break;
 

^ permalink raw reply related

* (unknown), 
From: 2012 SCAM VICTIMS COMPENSATIONS PAYMENTS. @ 2012-03-30 16:40 UTC (permalink / raw)


2012 SCAM VICTIMS COMPENSATIONS PAYMENTS.
ECOWAS NATIONS STATE/UNITED NATIONS
YOUR REF/PAYMENTS CODE: ECB/06654 FOR $500,000 USD ONLY.


Dear Victims of scam,
 This is to bring to your notice that our bank (ECOBANK INTL. PLC) is
delegated by the ECOWAS/UNITED NATIONS in Central Bank to compensate victims
of scam $500,000 (Five Hundred Thousand Dollars Only).

Your Name.___________________________
Address.___________________________
Phone .___________________________
Amount Defrauded.___________________________
Country.________________________

Send a copy of your response with the PAYMENT CODE
NUMBER(ECB/06654).

NAME: MR.CLEMENT SYLVANIUS
      SCAMMED VICTIM/REF/PAYMENTS CODE:
      ECB/06654 $500,000 USD.

Email: scamvictimstransfer_22@yahoo.co.jp

Yours Faithfully,
Mrs. Rosemary Peter
PUBLIC RELATIONS OFFICER
Copyright © 2012

^ permalink raw reply

* [REGRESSION][PATCH V4 1/3] bpf jit: Make the filter.c::__load_pointer helper non-static  for the jits
From: Jan Seiffert @ 2012-03-30 15:08 UTC (permalink / raw)
  To: netdev
  Cc: linux-kernel, linuxppc-dev, Matt Evans, Eric Dumazet,
	David S. Miller
In-Reply-To: <4F75CA89.4010709@googlemail.com>

The function is renamed to make it a little more clear what it does.
It is not added to any .h because it is not for general consumption, only for
bpf internal use (and so by the jits).

Signed-of-by: Jan Seiffert <kaffeemonster@googlemail.com>

--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -40,8 +40,12 @@
 #include <linux/reciprocal_div.h>
 #include <linux/ratelimit.h>
 
-/* No hurry in this branch */
-static void *__load_pointer(const struct sk_buff *skb, int k, unsigned int size)
+/*
+ * No hurry in this branch
+ *
+ * Exported for the bpf jit load helper.
+ */
+void *bpf_internal_load_pointer_neg_helper(const struct sk_buff *skb, int k, unsigned int size)
 {
 	u8 *ptr = NULL;
 
@@ -60,7 +64,7 @@ static inline void *load_pointer(const struct sk_buff *skb, int k,
 {
 	if (k >= 0)
 		return skb_header_pointer(skb, k, size, buffer);
-	return __load_pointer(skb, k, size);
+	return bpf_internal_load_pointer_neg_helper(skb, k, size);
 }
 
 /**

^ permalink raw reply

* [REGRESSION][PATCH V4 0/3] bpf jit drops the ball on negative memory references
From: Jan Seiffert @ 2012-03-30 15:00 UTC (permalink / raw)
  To: netdev
  Cc: linux-kernel, linuxppc-dev, Matt Evans, Eric Dumazet,
	David S. Miller

Consider the following test program:

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <pcap-bpf.h>

#define die(x) do {perror(x); return 1;} while (0)
struct bpf_insn udp_filter[] = {
	/*   0 */ BPF_STMT(BPF_LDX|BPF_W|BPF_IMM, -1048576+(0)), /* leax	net[0] */
	/*   1 */ BPF_STMT(BPF_LD|BPF_B|BPF_IND, 0),             /* ldb	[x+0] */
	/*   2 */ BPF_STMT(BPF_RET|BPF_A, 0),                    /* ret	a */
};

int main(int argc, char *argv[])
{
	char buf[512];
	struct sockaddr_in addr;
	struct bpf_program prg;
	socklen_t addr_s;
	ssize_t res;
	int fd;

	addr.sin_family = AF_INET;
	addr.sin_port = htons(5000);
	addr.sin_addr.s_addr = 0;
	addr_s = sizeof(addr);
	prg.bf_len = sizeof(udp_filter)/sizeof(udp_filter[0]);
	prg.bf_insns = udp_filter;
	if(-1 == (fd = socket(AF_INET, SOCK_DGRAM, 0)))
		die("socket");
	if(-1 == bind(fd, (struct sockaddr *)&addr, sizeof(addr)))
		die("bind");
	if(-1 == setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &prg, sizeof(prg)))
		die("setsockopt");
	res = recvfrom(fd, buf, sizeof(buf), 0, (struct sockaddr *)&addr, &addr_s);
	if(res != -1)
		printf("packet received: %zi bytes\n", res);
	else
		die("recvfrom");
	return 0;
}

when used with the bpf jit disabled works:
console 1 $ ./bpf
console 2 $ echo "hello" | nc -u localhost 5000
console 1: packet received: 6 bytes

When the bpf jit gets enabled (echo 100 >
/proc/sys/net/core/bpf_jit_enable) the same program stops working:
console 1 $ ./bpf
console 2 $ echo "hello" | nc -u localhost 5000
console 1:

The reason is that both jits (x86 and powerpc) do not handle negative
memory references like SKF_NET_OFF or SKF_LL_OFF, only the simple
ancillary data references are supported (by mapping to special
instructions).
In the case of an absolute reference, the jit aborts the translation
if a negative reference is seen, also a negative k on the indirect
load aborts the translation, but if X is negative to begin with, only
the error handler is reached at runtime which drops the whole packet.

Such a setup is useful to say filter bogus source addresses on an UDP
socket.

I propose the following patch series to fix this situation.
Patch 1 exports the helper function the interpreter uses.
Patch 2 incorporates the helper into the x86 jit (so it depends on patch 1).
Patch 3 incorporates the helper into the powerpc jit (so it depends on patch 1).

Lightly tested on x86, but the powerpc asm part is prop. wrong, could
need assistance.


Signed-of-by: Jan Seiffert <kaffeemonster@googlemail.com>

^ permalink raw reply

* Re: [REGRESSION][PATCH] bpf_jit drops the ball on indirect negative mem references
From: Jan Seiffert @ 2012-03-30 15:51 UTC (permalink / raw)
  To: Matt Evans
  Cc: <netdev@vger.kernel.org>, Eric Dumazet,
	<linux-kernel@vger.kernel.org>
In-Reply-To: <5D02999E-C16F-4D2B-9007-173AE054E614@ozlabs.org>

Matt Evans schrieb:
> Hi Jan,
> 
> On 30 Mar 2012, at 14:42, Jan Seiffert <kaffeemonster@googlemail.com> wrote:
> 
[snip]
>> Do you know where i can ping the powerpc guys a little bit harder?
> 
> No need (unless you mean a different guy), I have enough guilt as it
> is! :) (Sorry for no response, am moving house and am netless.)

Oh, ok, didn't know.

> I skimmed your patches on my phone but hope to be in a state to 
> review/test over the weekend or early next week. :)>> 

It would be great if you could review it.
With pinging harder i meant to get anyone fluent in powerpc asm to look
at the changes i made in the asm. I think the stack setup I've done is wrong.

> Cheers,
> 
> Matt
> 

Greetings
	Jan

> 
[snip]

-- 
Real programmer are surprised when their
odometer does not flip over from 000009
to 00000A.

^ permalink raw reply

* Re: [PATCH] net: add QCA alx Ethernet driver
From: Luis R. Rodriguez @ 2012-03-30 17:10 UTC (permalink / raw)
  To: David Miller
  Cc: xiong, netdev, linux-kernel, qca-linux-team, nic-devel, kgiori,
	chris.snook, mathieu, bryanh, Jesper Andersen, Julia Lawall
In-Reply-To: <CAB=NE6W-CYjEhbfYOv7XqXFGvdhZxRECqfAmgouaa5_j45gnOQ@mail.gmail.com>

On Wed, Mar 21, 2012 at 6:28 PM, Luis R. Rodriguez
<rodrigue@qca.qualcomm.com> wrote:
> On Tue, Feb 28, 2012 at 7:32 PM, David Miller <davem@davemloft.net> wrote:
>> From: "Huang, Xiong" <xiong@qca.qualcomm.com>
>> Date: Wed, 29 Feb 2012 03:11:14 +0000
>>
>>> We understand your concern.  To support the new chipset, do you
>>> think it's reasonable to upstream it as a new driver, not a
>>> replacement ?
>>
>> It depends upon how similar the chips are.
>
> OK.
>
>> To be honest tg3, as one example, supports quite a large array of
>> different pieces of hardware that use the same logical core.
>
> At certain point it becomes a pain in the ass to support older
> chipsets, and simply easier to leave the older driver to rot.
>
>> So that would be my litmus test about how different a chip needs
>> to be to deserve an entirely new driver.
>
> Understood.
>
>> I strongly suggest you try to get atl1c working properly.
>
> This is what I have recommended since the alx driver was rejected, and
> our team has been working on the atl1c driver now but we need to get
> the legal approval to get contributions out to atl1c (I know this is
> silly, but hey just letting you know).
>
> Anyway, in the meantime another topic has creeped up, and that is to
> share with BSD and also help kill proprietary drivers [0]. Me and
> Adrian intend on sharing our thoughts on how we intend on doing this
> at LF collab but was in hopes we can use alx as a test case. We've
> gone back to the drawing board for another simple driver to test our
> work against but... we come back to alx.
>
> Would it be worthwhile to consider alx upstream only for the newer
> chipsets (regardless of the litmus test, which I do agree with on
> technical grounds) in consideration for helping pave the way on
> killing proprietary drivers?
>
> [0] https://events.linuxfoundation.org/events/collaboration-summit/rodriguez-chadd

David, please us know if you think the above reason is worthy for
consideration of alx upstream, if at least for the newer chipsets. Our
engineers are ready to work on either approach, and we have a approval
take either route now. The sharing benefits however would make this a
great case to work on for the above mentioned project.

  Luis

^ permalink raw reply

* [PATCH] sky2: dont overwrite settings for PHY Quick link
From: Lino Sanfilippo @ 2012-03-30 17:28 UTC (permalink / raw)
  To: shemminger; +Cc: netdev, linux-kernel

This patch corrects a bug in function sky2_open() of the Marvell Yukon 2 driver
in which the settings for PHY quick link are overwritten.

Signed-off-by: Lino Sanfilippo <LinoSanfilippo@gmx.de>
---
 This applies against 3.3

 drivers/net/ethernet/marvell/sky2.c |    5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/marvell/sky2.c b/drivers/net/ethernet/marvell/sky2.c
index 760c2b1..d0132d8 100644
--- a/drivers/net/ethernet/marvell/sky2.c
+++ b/drivers/net/ethernet/marvell/sky2.c
@@ -1756,13 +1756,14 @@ static int sky2_open(struct net_device *dev)
 
 	sky2_hw_up(sky2);
 
+	/* Enable interrupts from phy/mac for port */
+	imask = sky2_read32(hw, B0_IMSK);
+
 	if (hw->chip_id == CHIP_ID_YUKON_OPT ||
 	    hw->chip_id == CHIP_ID_YUKON_PRM ||
 	    hw->chip_id == CHIP_ID_YUKON_OP_2)
 		imask |= Y2_IS_PHY_QLNK;	/* enable PHY Quick Link */
 
-	/* Enable interrupts from phy/mac for port */
-	imask = sky2_read32(hw, B0_IMSK);
 	imask |= portirq_msk[port];
 	sky2_write32(hw, B0_IMSK, imask);
 	sky2_read32(hw, B0_IMSK);
-- 
1.5.6.5

^ permalink raw reply related

* [PATCH] sky2: fix missing register reset on error path in sky2_test_msi()
From: Lino Sanfilippo @ 2012-03-30 17:36 UTC (permalink / raw)
  To: shemminger; +Cc: linux-kernel, netdev

In sky2_test_msi() the temporarily set SW IRQ in B0 register is not reset in case
that request_irq() fails.
With this patch we only set the interrupt mask if request_irq() was successful.

Signed-off-by: Lino Sanfilippo <LinoSanfilippo@gmx.de>
---
 This applies against 3.3

 drivers/net/ethernet/marvell/sky2.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/marvell/sky2.c b/drivers/net/ethernet/marvell/sky2.c
index 760c2b1..0e23ce4 100644
--- a/drivers/net/ethernet/marvell/sky2.c
+++ b/drivers/net/ethernet/marvell/sky2.c
@@ -4795,14 +4795,14 @@ static int __devinit sky2_test_msi(struct sky2_hw *hw)
 
 	init_waitqueue_head(&hw->msi_wait);
 
-	sky2_write32(hw, B0_IMSK, Y2_IS_IRQ_SW);
-
 	err = request_irq(pdev->irq, sky2_test_intr, 0, DRV_NAME, hw);
 	if (err) {
 		dev_err(&pdev->dev, "cannot assign irq %d\n", pdev->irq);
 		return err;
 	}
 
+	sky2_write32(hw, B0_IMSK, Y2_IS_IRQ_SW);
+
 	sky2_write8(hw, B0_CTST, CS_ST_SW_IRQ);
 	sky2_read8(hw, B0_CTST);
 
-- 
1.5.6.5

^ permalink raw reply related

* Re: TCP_MAXSEG option with TSO enabled
From: Rick Jones @ 2012-03-30 17:38 UTC (permalink / raw)
  To: Daniel Baluta; +Cc: netdev
In-Reply-To: <CAEnQRZC1sLW8BUOx2ov-S-UUSyfAi7Wem2mAzUHBHn2o9q-eRg@mail.gmail.com>

On 03/30/2012 04:33 AM, Daniel Baluta wrote:
> Hello,
>
> I am using TCP_MAXSEG option on an interface which has TSO enabled.
>
> strace output for connection looks as follows:
>
> socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 26
> setsockopt(26, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
> setsockopt(26, SOL_TCP, TCP_NODELAY, [1], 4) = 0
> setsockopt(26, SOL_TCP, TCP_MAXSEG, [300], 4) = 0
> connect(26, {sa_family=AF_INET, sin_port=htons(1935),
> sin_addr=inet_addr("10.10.0.1")}, 16) = -1 EINPROGRESS (Operation now
> in progress)
>
> I can see that MSS (300) is advertised in SYN packet, anyhow capturing
> the traffic
> I notice that are some TCP segments with length greater than MSS.
>
> Is this normal taking in consideration that TSO is enabled?

I would think so.  What do the netstat stats suggest for segments and 
bytes per segment when you are running your test?  You could always look 
for an on-the-wire packet trace.

Not sure that a trace on a receiver would give you that though - the 
inbound promiscuous tap may be above GRO (and almost certainly will be 
above LRO)

rick jones

>
> thanks,
> Daniel.
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* pull request: wireless 2012-03-30
From: John W. Linville @ 2012-03-30 17:55 UTC (permalink / raw)
  To: davem; +Cc: linux-wireless, netdev, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 5570 bytes --]

commit de312db345f9770b64ff39ef5a7f86f6358e93cc

Dave,

I have a few more small fixes, hopefully still in time for 3.4-rc1...

Rajkukmar provides us with a one-line timestamp correction related to
scanning in mac80211.  Sujith gives us a small fixup for a regression
in the handling of HT capability bits for ath9k.  Stanislav Yakovlev
is stepping-up as maintainer for the ipw2x00 drivers, so we'll add
him to MAINTAINERS.  Stanislav also gives us a fix for a thinko
that registers the wrong band information for ipw2200 and 802.11a.
Finally, Santosh Nayak adds some simple error checking to orinoco to
avoid some potential NULL pointer dereferences.

Please let me know if there are problems!

Thanks,

John

---

The following changes since commit 643c61e119459e9d750087b7b34be94491efebf9:

  rtlwifi: rtl8192ce: rtl8192cu: rtl8192de: Fix low-gain setting when scanning (2012-03-26 15:07:30 -0400)

are available in the git repository at:
  git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless.git master

Rajkumar Manoharan (1):
      mac80211: fix oper channel timestamp updation

Santosh Nayak (1):
      net: orinoco: add error handling for failed kmalloc().

Stanislav Yakovlev (2):
      net/wireless: ipw2x00: fix a typo in wiphy struct initilization
      MAINTAINERS: adding maintainer for ipw2x00

Sujith Manoharan (1):
      ath9k: Use HW HT capabilites properly

 MAINTAINERS                            |   12 ++++--------
 drivers/net/wireless/ath/ath9k/main.c  |    4 ++--
 drivers/net/wireless/ipw2x00/ipw2200.c |    4 ++--
 drivers/net/wireless/orinoco/main.c    |    8 ++++++++
 net/mac80211/scan.c                    |    2 +-
 5 files changed, 17 insertions(+), 13 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 0ddc77fe..09a79f9 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3519,17 +3519,13 @@ L:	linux-pm@vger.kernel.org
 S:	Supported
 F:	arch/x86/platform/mrst/pmu.*
 
-INTEL PRO/WIRELESS 2100 NETWORK CONNECTION SUPPORT
+INTEL PRO/WIRELESS 2100, 2200BG, 2915ABG NETWORK CONNECTION SUPPORT
+M:	Stanislav Yakovlev <stas.yakovlev@gmail.com>
 L:	linux-wireless@vger.kernel.org
-S:	Orphan
+S:	Maintained
 F:	Documentation/networking/README.ipw2100
-F:	drivers/net/wireless/ipw2x00/ipw2100.*
-
-INTEL PRO/WIRELESS 2915ABG NETWORK CONNECTION SUPPORT
-L:	linux-wireless@vger.kernel.org
-S:	Orphan
 F:	Documentation/networking/README.ipw2200
-F:	drivers/net/wireless/ipw2x00/ipw2200.*
+F:	drivers/net/wireless/ipw2x00/
 
 INTEL(R) TRUSTED EXECUTION TECHNOLOGY (TXT)
 M:	Joseph Cihula <joseph.cihula@intel.com>
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 3879485..215eb25 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -640,7 +640,7 @@ static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta,
 	an->sta = sta;
 	an->vif = vif;
 
-	if (sta->ht_cap.ht_supported) {
+	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
 		ath_tx_node_init(sc, an);
 		an->maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR +
 				     sta->ht_cap.ampdu_factor);
@@ -659,7 +659,7 @@ static void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta)
 	an->sta = NULL;
 #endif
 
-	if (sta->ht_cap.ht_supported)
+	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT)
 		ath_tx_node_cleanup(sc, an);
 }
 
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c
index 4fcdac6..2b02257 100644
--- a/drivers/net/wireless/ipw2x00/ipw2200.c
+++ b/drivers/net/wireless/ipw2x00/ipw2200.c
@@ -11507,9 +11507,9 @@ static int ipw_wdev_init(struct net_device *dev)
 			rc = -ENOMEM;
 			goto out;
 		}
-		/* translate geo->bg to a_band.channels */
+		/* translate geo->a to a_band.channels */
 		for (i = 0; i < geo->a_channels; i++) {
-			a_band->channels[i].band = IEEE80211_BAND_2GHZ;
+			a_band->channels[i].band = IEEE80211_BAND_5GHZ;
 			a_band->channels[i].center_freq = geo->a[i].freq;
 			a_band->channels[i].hw_value = geo->a[i].channel;
 			a_band->channels[i].max_power = geo->a[i].max_power;
diff --git a/drivers/net/wireless/orinoco/main.c b/drivers/net/wireless/orinoco/main.c
index dd6c64a..88e3ad2 100644
--- a/drivers/net/wireless/orinoco/main.c
+++ b/drivers/net/wireless/orinoco/main.c
@@ -1336,6 +1336,10 @@ static void qbuf_scan(struct orinoco_private *priv, void *buf,
 	unsigned long flags;
 
 	sd = kmalloc(sizeof(*sd), GFP_ATOMIC);
+	if (!sd) {
+		printk(KERN_ERR "%s: failed to alloc memory\n", __func__);
+		return;
+	}
 	sd->buf = buf;
 	sd->len = len;
 	sd->type = type;
@@ -1353,6 +1357,10 @@ static void qabort_scan(struct orinoco_private *priv)
 	unsigned long flags;
 
 	sd = kmalloc(sizeof(*sd), GFP_ATOMIC);
+	if (!sd) {
+		printk(KERN_ERR "%s: failed to alloc memory\n", __func__);
+		return;
+	}
 	sd->len = -1; /* Abort */
 
 	spin_lock_irqsave(&priv->scan_lock, flags);
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 33cd169..c70e176 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -370,7 +370,7 @@ static int ieee80211_start_sw_scan(struct ieee80211_local *local)
 	 */
 	drv_sw_scan_start(local);
 
-	local->leave_oper_channel_time = 0;
+	local->leave_oper_channel_time = jiffies;
 	local->next_scan_state = SCAN_DECISION;
 	local->scan_channel_idx = 0;
 
-- 
John W. Linville		Someday the world will need a hero, and you
linville@tuxdriver.com			might be all we have.  Be ready.

[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply related

* Re: pull request: wireless 2012-03-30
From: Oliver Hartkopp @ 2012-03-30 18:06 UTC (permalink / raw)
  To: John W. Linville; +Cc: davem, linux-wireless, netdev, linux-kernel
In-Reply-To: <20120330175533.GC8273@tuxdriver.com>

Hello John,

there are at least two patches that i know from that fix issues in the current
3.4-merge tree.

[PATCH] iwlwifi: fix unused variable warning
http://marc.info/?l=linux-wireless&m=133266148006409&w=2
Acked-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
http://marc.info/?l=linux-wireless&m=133272671523532&w=2

[PATCH 3.4] mac80211: fix association beacon wait timeout
http://marc.info/?l=linux-wireless&m=133296144416566&w=2
Tested-by: Oliver Hartkopp <socketcan@hartkopp.net>
http://marc.info/?l=linux-wireless&m=133296423617914&w=2

Did you miss them?

Regards,
Oliver

On 30.03.2012 19:55, John W. Linville wrote:

> commit de312db345f9770b64ff39ef5a7f86f6358e93cc
> 
> Dave,
> 
> I have a few more small fixes, hopefully still in time for 3.4-rc1...
> 
> Rajkukmar provides us with a one-line timestamp correction related to
> scanning in mac80211.  Sujith gives us a small fixup for a regression
> in the handling of HT capability bits for ath9k.  Stanislav Yakovlev
> is stepping-up as maintainer for the ipw2x00 drivers, so we'll add
> him to MAINTAINERS.  Stanislav also gives us a fix for a thinko
> that registers the wrong band information for ipw2200 and 802.11a.
> Finally, Santosh Nayak adds some simple error checking to orinoco to
> avoid some potential NULL pointer dereferences.
> 
> Please let me know if there are problems!
> 
> Thanks,
> 
> John
> 
> ---
> 
> The following changes since commit 643c61e119459e9d750087b7b34be94491efebf9:
> 
>   rtlwifi: rtl8192ce: rtl8192cu: rtl8192de: Fix low-gain setting when scanning (2012-03-26 15:07:30 -0400)
> 
> are available in the git repository at:
>   git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless.git master
> 
> Rajkumar Manoharan (1):
>       mac80211: fix oper channel timestamp updation
> 
> Santosh Nayak (1):
>       net: orinoco: add error handling for failed kmalloc().
> 
> Stanislav Yakovlev (2):
>       net/wireless: ipw2x00: fix a typo in wiphy struct initilization
>       MAINTAINERS: adding maintainer for ipw2x00
> 
> Sujith Manoharan (1):
>       ath9k: Use HW HT capabilites properly
> 
>  MAINTAINERS                            |   12 ++++--------
>  drivers/net/wireless/ath/ath9k/main.c  |    4 ++--
>  drivers/net/wireless/ipw2x00/ipw2200.c |    4 ++--
>  drivers/net/wireless/orinoco/main.c    |    8 ++++++++
>  net/mac80211/scan.c                    |    2 +-
>  5 files changed, 17 insertions(+), 13 deletions(-)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 0ddc77fe..09a79f9 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -3519,17 +3519,13 @@ L:	linux-pm@vger.kernel.org
>  S:	Supported
>  F:	arch/x86/platform/mrst/pmu.*
>  
> -INTEL PRO/WIRELESS 2100 NETWORK CONNECTION SUPPORT
> +INTEL PRO/WIRELESS 2100, 2200BG, 2915ABG NETWORK CONNECTION SUPPORT
> +M:	Stanislav Yakovlev <stas.yakovlev@gmail.com>
>  L:	linux-wireless@vger.kernel.org
> -S:	Orphan
> +S:	Maintained
>  F:	Documentation/networking/README.ipw2100
> -F:	drivers/net/wireless/ipw2x00/ipw2100.*
> -
> -INTEL PRO/WIRELESS 2915ABG NETWORK CONNECTION SUPPORT
> -L:	linux-wireless@vger.kernel.org
> -S:	Orphan
>  F:	Documentation/networking/README.ipw2200
> -F:	drivers/net/wireless/ipw2x00/ipw2200.*
> +F:	drivers/net/wireless/ipw2x00/
>  
>  INTEL(R) TRUSTED EXECUTION TECHNOLOGY (TXT)
>  M:	Joseph Cihula <joseph.cihula@intel.com>
> diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
> index 3879485..215eb25 100644
> --- a/drivers/net/wireless/ath/ath9k/main.c
> +++ b/drivers/net/wireless/ath/ath9k/main.c
> @@ -640,7 +640,7 @@ static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta,
>  	an->sta = sta;
>  	an->vif = vif;
>  
> -	if (sta->ht_cap.ht_supported) {
> +	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
>  		ath_tx_node_init(sc, an);
>  		an->maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR +
>  				     sta->ht_cap.ampdu_factor);
> @@ -659,7 +659,7 @@ static void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta)
>  	an->sta = NULL;
>  #endif
>  
> -	if (sta->ht_cap.ht_supported)
> +	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT)
>  		ath_tx_node_cleanup(sc, an);
>  }
>  
> diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c
> index 4fcdac6..2b02257 100644
> --- a/drivers/net/wireless/ipw2x00/ipw2200.c
> +++ b/drivers/net/wireless/ipw2x00/ipw2200.c
> @@ -11507,9 +11507,9 @@ static int ipw_wdev_init(struct net_device *dev)
>  			rc = -ENOMEM;
>  			goto out;
>  		}
> -		/* translate geo->bg to a_band.channels */
> +		/* translate geo->a to a_band.channels */
>  		for (i = 0; i < geo->a_channels; i++) {
> -			a_band->channels[i].band = IEEE80211_BAND_2GHZ;
> +			a_band->channels[i].band = IEEE80211_BAND_5GHZ;
>  			a_band->channels[i].center_freq = geo->a[i].freq;
>  			a_band->channels[i].hw_value = geo->a[i].channel;
>  			a_band->channels[i].max_power = geo->a[i].max_power;
> diff --git a/drivers/net/wireless/orinoco/main.c b/drivers/net/wireless/orinoco/main.c
> index dd6c64a..88e3ad2 100644
> --- a/drivers/net/wireless/orinoco/main.c
> +++ b/drivers/net/wireless/orinoco/main.c
> @@ -1336,6 +1336,10 @@ static void qbuf_scan(struct orinoco_private *priv, void *buf,
>  	unsigned long flags;
>  
>  	sd = kmalloc(sizeof(*sd), GFP_ATOMIC);
> +	if (!sd) {
> +		printk(KERN_ERR "%s: failed to alloc memory\n", __func__);
> +		return;
> +	}
>  	sd->buf = buf;
>  	sd->len = len;
>  	sd->type = type;
> @@ -1353,6 +1357,10 @@ static void qabort_scan(struct orinoco_private *priv)
>  	unsigned long flags;
>  
>  	sd = kmalloc(sizeof(*sd), GFP_ATOMIC);
> +	if (!sd) {
> +		printk(KERN_ERR "%s: failed to alloc memory\n", __func__);
> +		return;
> +	}
>  	sd->len = -1; /* Abort */
>  
>  	spin_lock_irqsave(&priv->scan_lock, flags);
> diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
> index 33cd169..c70e176 100644
> --- a/net/mac80211/scan.c
> +++ b/net/mac80211/scan.c
> @@ -370,7 +370,7 @@ static int ieee80211_start_sw_scan(struct ieee80211_local *local)
>  	 */
>  	drv_sw_scan_start(local);
>  
> -	local->leave_oper_channel_time = 0;
> +	local->leave_oper_channel_time = jiffies;
>  	local->next_scan_state = SCAN_DECISION;
>  	local->scan_channel_idx = 0;
>  

^ permalink raw reply

* Re: TCP_MAXSEG option with TSO enabled
From: Daniel Baluta @ 2012-03-30 18:07 UTC (permalink / raw)
  To: Rick Jones; +Cc: netdev
In-Reply-To: <4F75EF78.4060402@hp.com>

On Fri, Mar 30, 2012 at 8:38 PM, Rick Jones <rick.jones2@hp.com> wrote:
> On 03/30/2012 04:33 AM, Daniel Baluta wrote:
>>
>> Hello,
>>
>> I am using TCP_MAXSEG option on an interface which has TSO enabled.
>>
>> strace output for connection looks as follows:
>>
>> socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 26
>> setsockopt(26, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
>> setsockopt(26, SOL_TCP, TCP_NODELAY, [1], 4) = 0
>> setsockopt(26, SOL_TCP, TCP_MAXSEG, [300], 4) = 0
>> connect(26, {sa_family=AF_INET, sin_port=htons(1935),
>> sin_addr=inet_addr("10.10.0.1")}, 16) = -1 EINPROGRESS (Operation now
>> in progress)
>>
>> I can see that MSS (300) is advertised in SYN packet, anyhow capturing
>> the traffic
>> I notice that are some TCP segments with length greater than MSS.
>>
>> Is this normal taking in consideration that TSO is enabled?
>
>
> I would think so.  What do the netstat stats suggest for segments and bytes
> per segment when you are running your test?  You could always look for an
> on-the-wire packet trace.
>
> Not sure that a trace on a receiver would give you that though - the inbound
> promiscuous tap may be above GRO (and almost certainly will be above LRO)

Thanks Rick. Indeed on-the-wire capture looks fine. I have TSO enabled
at sender and LRO at receiver, everything makes sense now.

thanks,
Daniel.

^ permalink raw reply

* Re: pull request: wireless 2012-03-30
From: John W. Linville @ 2012-03-30 18:30 UTC (permalink / raw)
  To: Oliver Hartkopp; +Cc: davem, linux-wireless, netdev, linux-kernel
In-Reply-To: <4F75F620.9030101@hartkopp.net>

On Fri, Mar 30, 2012 at 08:06:24PM +0200, Oliver Hartkopp wrote:
> Hello John,
> 
> there are at least two patches that i know from that fix issues in the current
> 3.4-merge tree.
> 
> [PATCH] iwlwifi: fix unused variable warning
> http://marc.info/?l=linux-wireless&m=133266148006409&w=2
> Acked-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
> http://marc.info/?l=linux-wireless&m=133272671523532&w=2
> 
> [PATCH 3.4] mac80211: fix association beacon wait timeout
> http://marc.info/?l=linux-wireless&m=133296144416566&w=2
> Tested-by: Oliver Hartkopp <socketcan@hartkopp.net>
> http://marc.info/?l=linux-wireless&m=133296423617914&w=2
> 
> Did you miss them?
> 
> Regards,
> Oliver

No, I didn't.  Please be patient.

John
-- 
John W. Linville		Someday the world will need a hero, and you
linville@tuxdriver.com			might be all we have.  Be ready.

^ permalink raw reply

* Re: [PATCH] net: add QCA alx Ethernet driver
From: Luis R. Rodriguez @ 2012-03-30 18:31 UTC (permalink / raw)
  To: Dave Taht
  Cc: davem, netdev, linux-kernel, qca-linux-team, nic-devel, kgiori,
	chris.snook, mathieu, bryanh
In-Reply-To: <CAA93jw4NwHaLazxK2Eo6a6TuvF3svqdZjTpHUwOyEHv-Q=busQ@mail.gmail.com>

On Fri, Mar 30, 2012 at 11:16 AM, Dave Taht <dave.taht@gmail.com> wrote:
>
>
> On Wed, Feb 29, 2012 at 1:50 AM, Luis R. Rodriguez
> <rodrigue@qca.qualcomm.com> wrote:
>>
>> From: Luis R. Rodriguez <mcgrof@frijolero.org>
>>
>> The next patch adds the new QCA alx Ethernet driver that
>> supercedes the atl1c Ethernet driver. For details please
>> read the commit log of the patch. Given the size you can
>> download the patch from:
>
>
>
>>
>>
>>
>> http://bombadil.infradead.org/~mcgrof/2012/02/28/add-alx-next-20120228.patch
>> sha1sum: 8a8f7b6f1cbe737e70ec3b3eda483a6925fd9bd6
>>
>
> The shiny graph was rather impressive vs a vs the old driver.
>
> https://www.linuxfoundation.org/sites/main/files/alx-iperf.jpg
>
> A quick grep showed no BQL support. :(

Good point, we'll add that to our TODO list.

  Luis

^ permalink raw reply

* Re: [REGRESSION][PATCH V4 1/3] bpf jit: Make the filter.c::__load_pointer helper non-static  for the jits
From: Eric Dumazet @ 2012-03-30 18:56 UTC (permalink / raw)
  To: Jan Seiffert
  Cc: netdev, linux-kernel, linuxppc-dev, Matt Evans, David S. Miller
In-Reply-To: <4F75CC63.10405@googlemail.com>

On Fri, 2012-03-30 at 17:08 +0200, Jan Seiffert wrote:
> The function is renamed to make it a little more clear what it does.
> It is not added to any .h because it is not for general consumption, only for
> bpf internal use (and so by the jits).
> 
> Signed-of-by: Jan Seiffert <kaffeemonster@googlemail.com>
> 

Missing "---" line separator (check Documentation/SubmittingPatches line
490)

You can check http://patchwork.ozlabs.org/patch/149683/ and see there is
a problem, compared to http://patchwork.ozlabs.org/patch/149441/ for
example

> --- a/net/core/filter.c
> +++ b/net/core/filter.c
> @@ -40,8 +40,12 @@
>  #include <linux/reciprocal_div.h>
>  #include <linux/ratelimit.h>
>  
> -/* No hurry in this branch */
> -static void *__load_pointer(const struct sk_buff *skb, int k, unsigned int size)
> +/*
> + * No hurry in this branch
> + *
> + * Exported for the bpf jit load helper.
> + */

Seems good to me, maybe add a strong warning in the comment to say that
function prototype can NOT change without major surgery in ASM files,
since assembler wont catch the prototype change for us.

Acked-by: Eric Dumazet <eric.dumazet@gmail.com>

^ permalink raw reply

* Re: [REGRESSION][PATCH V4 2/3] bpf jit: Let the x86 jit handle negative offsets
From: Eric Dumazet @ 2012-03-30 18:58 UTC (permalink / raw)
  To: kaffeemonster; +Cc: netdev, linux-kernel, David S. Miller
In-Reply-To: <4F75D015.30609@googlemail.com>

On Fri, 2012-03-30 at 17:24 +0200, Jan Seiffert wrote:
> Now the helper function from filter.c for negative offsets is exported,
> it can be used it in the jit to handle negative offsets.
> 
> First modify the asm load helper functions to handle:
> - know positive offsets
> - know negative offsets
> - any offset
> 
> then the compiler can be modified to explicitly use these helper
> when appropriate.
> 
> This fixes the case of a negative X register and allows to lift
> the restriction that bpf programs with negative offsets can't
> be jited.
> 
> Signed-of-by: Jan Seiffert <kaffeemonster@googlemail.com>

Nice work Jan, thanks a lot.

Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>

^ permalink raw reply

* question about frag_can_reassemble()
From: Dan Carpenter @ 2012-03-30 20:02 UTC (permalink / raw)
  To: Sven Eckelmann
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
	b.a.t.m.a.n-ZwoEplunGu2X36UT3dwllkB+6BGkLq7r

Hi Sven,

I had a question about the code in frag_can_reassemble().

net/batman-adv/unicast.h
    51  
    52          merged_size = (skb->len - sizeof(*unicast_packet)) * 2;
                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    53          merged_size += sizeof(struct unicast_packet) + uneven_correction;
    54  
    55          return merged_size <= mtu;
    56  }

Can the skb->len be less than sizeof(*unicast_packet) (ie 20 bytes)?
If "len" is less than 10 then we would return false but if it's
over 10 then we would return true.  Roughly.

regards,
dan carpenter

^ permalink raw reply

* [PATCH v2 00/15] mark const init data with __initconst instead of __initdata
From: Uwe Kleine-König @ 2012-03-30 20:03 UTC (permalink / raw)
  To: linux-kernel, Andrew Morton
  Cc: Andrew Lunn, Christoph Lameter, linux-mips, Tony Lindgren,
	Benjamin Herrenschmidt, Linus Walleij, Matt Porter, Nicolas Ferre,
	Matthew Garrett, platform-driver-x86, Grant Likely,
	ibm-acpi-devel, Randy Dunlap, linux-mtd, Sekhar Nori,
	Daniel Walker, lm-sensors, Klaus Kudielka, Guenter Roeck,
	Kevin Hilman, linux-ia64, Kukjin Kim, Russell King, Samuel Ortiz
In-Reply-To: <20120329211131.GA31250@pengutronix.de>

Hello,

On Thu, Mar 29, 2012 at 11:11:31PM +0200, Uwe Kleine-König wrote:
> this series fixes a common error to use __initdata to mark const
> variables. Most of the time this works well enough to go unnoticed
> (though I wonder why the linker doesn't warn about that).
> Just try adding something like
> 
> 	int something __initdata;
> 
> to one of the patched files and compile to see the error.
> 
> While touching these annotations I also corrected the position where it
> was wrong to go between the variable name and the =.
> 
> Note this series is not compile tested.
I now dropped the wrong annotations. So two patches became obsolete
(mtd and percpu). Note that I also dropped fixing the position of
__initdata if changing it to __initconst was wrong. (I think if
__initdata is placed before the variable name it doesn't have any
effect.)

I didn't promote the Acks I got because all acked changes changed in v2.

For the details changed in each patch see the changelogs in the
respective patch mails that I follow up to this mail.

Thanks
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-König            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply

* [PATCH v2 04/15] net: mark const init data with __initconst instead of __initdata
From: Uwe Kleine-König @ 2012-03-30 20:04 UTC (permalink / raw)
  To: linux-kernel, Andrew Morton
  Cc: kernel, Andreas Koensgen, Klaus Kudielka, Joerg Reuter,
	Jean-Paul Roubelat, netdev, linux-hams
In-Reply-To: <20120330200358.GV15647@pengutronix.de>

As long as there is no other non-const variable marked __initdata in the
same compilation unit it doesn't hurt. If there were one however
compilation would fail with

	error: $variablename causes a section type conflict

because a section containing const variables is marked read only and so
cannot contain non-const variables.

Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Cc: Andreas Koensgen <ajk@comnets.uni-bremen.de>
Cc: Klaus Kudielka <klaus.kudielka@ieee.org>
Cc: Joerg Reuter <jreuter@yaina.de>
Cc: Jean-Paul Roubelat <jpr@f6fbb.org>
Cc: netdev@vger.kernel.org
Cc: linux-hams@vger.kernel.org
---
changes since (implicit) v1:
 - drop wrong changes in drivers/net/ethernet/8390/ne3210.c

 drivers/net/hamradio/6pack.c    |    4 ++--
 drivers/net/hamradio/bpqether.c |    2 +-
 drivers/net/hamradio/mkiss.c    |    4 ++--
 drivers/net/hamradio/scc.c      |    2 +-
 drivers/net/hamradio/yam.c      |    2 +-
 drivers/net/tokenring/smctr.c   |    2 +-
 drivers/net/wan/z85230.c        |    2 +-
 7 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c
index 64783a0..d225a2a 100644
--- a/drivers/net/hamradio/6pack.c
+++ b/drivers/net/hamradio/6pack.c
@@ -811,9 +811,9 @@ static struct tty_ldisc_ops sp_ldisc = {
 
 /* Initialize 6pack control device -- register 6pack line discipline */
 
-static const char msg_banner[]  __initdata = KERN_INFO \
+static const char msg_banner[]  __initconst = KERN_INFO \
 	"AX.25: 6pack driver, " SIXPACK_VERSION "\n";
-static const char msg_regfail[] __initdata = KERN_ERR  \
+static const char msg_regfail[] __initconst = KERN_ERR  \
 	"6pack: can't register line discipline (err = %d)\n";
 
 static int __init sixpack_init_driver(void)
diff --git a/drivers/net/hamradio/bpqether.c b/drivers/net/hamradio/bpqether.c
index 76d5477..c2e5497 100644
--- a/drivers/net/hamradio/bpqether.c
+++ b/drivers/net/hamradio/bpqether.c
@@ -87,7 +87,7 @@
 
 #include <linux/bpqether.h>
 
-static const char banner[] __initdata = KERN_INFO \
+static const char banner[] __initconst = KERN_INFO \
 	"AX.25: bpqether driver version 004\n";
 
 static char bcast_addr[6]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c
index aed1a61..d694215 100644
--- a/drivers/net/hamradio/mkiss.c
+++ b/drivers/net/hamradio/mkiss.c
@@ -997,9 +997,9 @@ static struct tty_ldisc_ops ax_ldisc = {
 	.write_wakeup	= mkiss_write_wakeup
 };
 
-static const char banner[] __initdata = KERN_INFO \
+static const char banner[] __initconst = KERN_INFO \
 	"mkiss: AX.25 Multikiss, Hans Albas PE1AYX\n";
-static const char msg_regfail[] __initdata = KERN_ERR \
+static const char msg_regfail[] __initconst = KERN_ERR \
 	"mkiss: can't register line discipline (err = %d)\n";
 
 static int __init mkiss_init_driver(void)
diff --git a/drivers/net/hamradio/scc.c b/drivers/net/hamradio/scc.c
index efc6c97..1b4a47b 100644
--- a/drivers/net/hamradio/scc.c
+++ b/drivers/net/hamradio/scc.c
@@ -182,7 +182,7 @@
 
 #include "z8530.h"
 
-static const char banner[] __initdata = KERN_INFO \
+static const char banner[] __initconst = KERN_INFO \
 	"AX.25: Z8530 SCC driver version "VERSION".dl1bke\n";
 
 static void t_dwait(unsigned long);
diff --git a/drivers/net/hamradio/yam.c b/drivers/net/hamradio/yam.c
index 5a6412e..c6645f1 100644
--- a/drivers/net/hamradio/yam.c
+++ b/drivers/net/hamradio/yam.c
@@ -76,7 +76,7 @@
 /* --------------------------------------------------------------------- */
 
 static const char yam_drvname[] = "yam";
-static const char yam_drvinfo[] __initdata = KERN_INFO \
+static const char yam_drvinfo[] __initconst = KERN_INFO \
 	"YAM driver version 0.8 by F1OAT/F6FBB\n";
 
 /* --------------------------------------------------------------------- */
diff --git a/drivers/net/tokenring/smctr.c b/drivers/net/tokenring/smctr.c
index cb35fb7..90b5f1e 100644
--- a/drivers/net/tokenring/smctr.c
+++ b/drivers/net/tokenring/smctr.c
@@ -59,7 +59,7 @@
 
 #include "smctr.h"               /* Our Stuff */
 
-static const char version[] __initdata =
+static const char version[] __initconst =
 	KERN_INFO "smctr.c: v1.4 7/12/00 by jschlst@samba.org\n";
 static const char cardname[] = "smctr";
 
diff --git a/drivers/net/wan/z85230.c b/drivers/net/wan/z85230.c
index 0e57690..feacc3b 100644
--- a/drivers/net/wan/z85230.c
+++ b/drivers/net/wan/z85230.c
@@ -1775,7 +1775,7 @@ EXPORT_SYMBOL(z8530_queue_xmit);
 /*
  *	Module support
  */
-static const char banner[] __initdata =
+static const char banner[] __initconst =
 	KERN_INFO "Generic Z85C30/Z85230 interface driver v0.02\n";
 
 static int __init z85230_init_driver(void)
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-hams" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related

* [PATCH] Fix NULL pointer dereference on firmware name for early calls to get_drvinfo.
From: Bill Nottingham @ 2012-03-30 20:24 UTC (permalink / raw)
  To: inaky.perez-gonzalez, wimax, netdev

The driver comments show an initialization sequence of:
 * i2400m_setup()
 *   i2400m->bus_setup()
 *   i2400m_bootrom_init()
 *   register_netdev()
 *   wimax_dev_add()
 *   i2400m_dev_start()
 *     __i2400m_dev_start()
 *       i2400m_dev_bootstrap()

dev_bootstrap() is where the firmware is loaded. So, if something calls
get_drvinfo() from a register_netdevice_notifier (such as the cnic driver),
we won't have a firmware name, and strncpy will crash.

https://bugzilla.redhat.com/show_bug.cgi?id=808603

Signed-off-by: Bill Nottingham <notting@redhat.com>
---
 drivers/net/wimax/i2400m/netdev.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wimax/i2400m/netdev.c b/drivers/net/wimax/i2400m/netdev.c
index 63e4b70..e44f4e2 100644
--- a/drivers/net/wimax/i2400m/netdev.c
+++ b/drivers/net/wimax/i2400m/netdev.c
@@ -597,7 +597,8 @@ static void i2400m_get_drvinfo(struct net_device *net_dev,
 	struct i2400m *i2400m = net_dev_to_i2400m(net_dev);
 
 	strncpy(info->driver, KBUILD_MODNAME, sizeof(info->driver) - 1);
-	strncpy(info->fw_version, i2400m->fw_name, sizeof(info->fw_version) - 1);
+	if (i2400m->fw_name)
+		strncpy(info->fw_version, i2400m->fw_name, sizeof(info->fw_version) - 1);
 	if (net_dev->dev.parent)
 		strncpy(info->bus_info, dev_name(net_dev->dev.parent),
 			sizeof(info->bus_info) - 1);
-- 
1.7.9.3

^ permalink raw reply related

* Re: [PATCH] net: add QCA alx Ethernet driver
From: David Miller @ 2012-03-30 20:45 UTC (permalink / raw)
  To: rodrigue
  Cc: xiong, netdev, linux-kernel, qca-linux-team, nic-devel, kgiori,
	chris.snook, mathieu, bryanh, jespera, julia
In-Reply-To: <CAB=NE6WPWmrTZ__JQViqhde-krBsbM5G+ZQgK0pNC+W909u_ew@mail.gmail.com>

From: "Luis R. Rodriguez" <rodrigue@qca.qualcomm.com>
Date: Fri, 30 Mar 2012 10:10:55 -0700

> On Wed, Mar 21, 2012 at 6:28 PM, Luis R. Rodriguez
> <rodrigue@qca.qualcomm.com> wrote:
>> On Tue, Feb 28, 2012 at 7:32 PM, David Miller <davem@davemloft.net> wrote:
>> Would it be worthwhile to consider alx upstream only for the newer
>> chipsets (regardless of the litmus test, which I do agree with on
>> technical grounds) in consideration for helping pave the way on
>> killing proprietary drivers?
 ...
> David, please us know if you think the above reason is worthy for
> consideration of alx upstream, if at least for the newer chipsets.

Submitting alx that only supports the newer chipsets is fine.

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox