* [Qemu-devel] [PATCH 0/3] rtl8139: cleanups
@ 2015-08-03 12:15 Stefan Hajnoczi
2015-08-03 12:15 ` [Qemu-devel] [PATCH 1/3] rtl8139: remove duplicate net/eth.h definitions Stefan Hajnoczi
` (4 more replies)
0 siblings, 5 replies; 6+ messages in thread
From: Stefan Hajnoczi @ 2015-08-03 12:15 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell, jasowang, Stefan Hajnoczi
After addressing CVE-2015-5165 there were several additional rtl8139 cleanups
that I'm sending separately since they are not security fixes.
These patches eliminate duplicate eth.h structs/macros and fix unaligned memory
accesses in tx offload.
Stefan Hajnoczi (3):
rtl8139: remove duplicate net/eth.h definitions
rtl8139: use net/eth.h macros instead of custom macros
rtl8139: use ldl/stl wrapper for unaligned 32-bit access
hw/net/rtl8139.c | 103 +++++++++++++++----------------------------------------
1 file changed, 27 insertions(+), 76 deletions(-)
--
2.4.3
^ permalink raw reply [flat|nested] 6+ messages in thread
* [Qemu-devel] [PATCH 1/3] rtl8139: remove duplicate net/eth.h definitions
2015-08-03 12:15 [Qemu-devel] [PATCH 0/3] rtl8139: cleanups Stefan Hajnoczi
@ 2015-08-03 12:15 ` Stefan Hajnoczi
2015-08-03 12:15 ` [Qemu-devel] [PATCH 2/3] rtl8139: use net/eth.h macros instead of custom macros Stefan Hajnoczi
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Stefan Hajnoczi @ 2015-08-03 12:15 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell, jasowang, Stefan Hajnoczi
The transmit offload features inspect Ethernet, IP, TCP, and UDP
headers. Avoid redefining these net/eth.h structs.
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
hw/net/rtl8139.c | 57 +++++---------------------------------------------------
1 file changed, 5 insertions(+), 52 deletions(-)
diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c
index edbb61c..6de94d9 100644
--- a/hw/net/rtl8139.c
+++ b/hw/net/rtl8139.c
@@ -56,6 +56,7 @@
#include "sysemu/dma.h"
#include "qemu/timer.h"
#include "net/net.h"
+#include "net/eth.h"
#include "hw/loader.h"
#include "sysemu/sysemu.h"
#include "qemu/iov.h"
@@ -75,7 +76,6 @@
#define ETHER_ADDR_LEN 6
#define ETHER_TYPE_LEN 2
#define ETH_HLEN (ETHER_ADDR_LEN * 2 + ETHER_TYPE_LEN)
-#define ETH_P_IP 0x0800 /* Internet Protocol packet */
#define ETH_P_8021Q 0x8100 /* 802.1Q VLAN Extended Header */
#define ETH_MTU 1500
@@ -1868,55 +1868,8 @@ static int rtl8139_transmit_one(RTL8139State *s, int descriptor)
}
/* structures and macros for task offloading */
-typedef struct ip_header
-{
- uint8_t ip_ver_len; /* version and header length */
- uint8_t ip_tos; /* type of service */
- uint16_t ip_len; /* total length */
- uint16_t ip_id; /* identification */
- uint16_t ip_off; /* fragment offset field */
- uint8_t ip_ttl; /* time to live */
- uint8_t ip_p; /* protocol */
- uint16_t ip_sum; /* checksum */
- uint32_t ip_src,ip_dst; /* source and dest address */
-} ip_header;
-
-#define IP_HEADER_VERSION_4 4
-#define IP_HEADER_VERSION(ip) ((ip->ip_ver_len >> 4)&0xf)
#define IP_HEADER_LENGTH(ip) (((ip->ip_ver_len)&0xf) << 2)
-typedef struct tcp_header
-{
- uint16_t th_sport; /* source port */
- uint16_t th_dport; /* destination port */
- uint32_t th_seq; /* sequence number */
- uint32_t th_ack; /* acknowledgement number */
- uint16_t th_offset_flags; /* data offset, reserved 6 bits, TCP protocol flags */
- uint16_t th_win; /* window */
- uint16_t th_sum; /* checksum */
- uint16_t th_urp; /* urgent pointer */
-} tcp_header;
-
-typedef struct udp_header
-{
- uint16_t uh_sport; /* source port */
- uint16_t uh_dport; /* destination port */
- uint16_t uh_ulen; /* udp length */
- uint16_t uh_sum; /* udp checksum */
-} udp_header;
-
-typedef struct ip_pseudo_header
-{
- uint32_t ip_src;
- uint32_t ip_dst;
- uint8_t zeros;
- uint8_t ip_proto;
- uint16_t ip_payload;
-} ip_pseudo_header;
-
-#define IP_PROTO_TCP 6
-#define IP_PROTO_UDP 17
-
#define TCP_HEADER_DATA_OFFSET(tcp) (((be16_to_cpu(tcp->th_offset_flags) >> 12)&0xf) << 2)
#define TCP_FLAGS_ONLY(flags) ((flags)&0x3f)
#define TCP_HEADER_FLAGS(tcp) TCP_FLAGS_ONLY(be16_to_cpu(tcp->th_offset_flags))
@@ -2151,12 +2104,12 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
DPRINTF("+++ C+ mode offloaded task checksum\n");
/* Large enough for Ethernet and IP headers? */
- if (saved_size < ETH_HLEN + sizeof(ip_header)) {
+ if (saved_size < ETH_HLEN + sizeof(struct ip_header)) {
goto skip_offload;
}
/* ip packet header */
- ip_header *ip = NULL;
+ struct ip_header *ip = NULL;
int hlen = 0;
uint8_t ip_protocol = 0;
uint16_t ip_data_len = 0;
@@ -2176,7 +2129,7 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
eth_payload_data = saved_buffer + ETH_HLEN;
eth_payload_len = saved_size - ETH_HLEN;
- ip = (ip_header*)eth_payload_data;
+ ip = (struct ip_header*)eth_payload_data;
if (IP_HEADER_VERSION(ip) != IP_HEADER_VERSION_4) {
DPRINTF("+++ C+ mode packet has bad IP version %d "
@@ -2186,7 +2139,7 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
}
hlen = IP_HEADER_LENGTH(ip);
- if (hlen < sizeof(ip_header) || hlen > eth_payload_len) {
+ if (hlen < sizeof(struct ip_header) || hlen > eth_payload_len) {
goto skip_offload;
}
--
2.4.3
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [Qemu-devel] [PATCH 2/3] rtl8139: use net/eth.h macros instead of custom macros
2015-08-03 12:15 [Qemu-devel] [PATCH 0/3] rtl8139: cleanups Stefan Hajnoczi
2015-08-03 12:15 ` [Qemu-devel] [PATCH 1/3] rtl8139: remove duplicate net/eth.h definitions Stefan Hajnoczi
@ 2015-08-03 12:15 ` Stefan Hajnoczi
2015-08-03 12:15 ` [Qemu-devel] [PATCH 3/3] rtl8139: use ldl/stl wrapper for unaligned 32-bit access Stefan Hajnoczi
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Stefan Hajnoczi @ 2015-08-03 12:15 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell, jasowang, Stefan Hajnoczi
Eliminate the following "custom" macros since they are just duplicates
of net/eth.h macros under a different name:
ETHER_ADDR_LEN -> ETH_ALEN
ETH_P_8021Q -> ETH_P_VLAN
IP_HEADER_LENGTH -> IP_HDR_GET_LEN
TCP_FLAG_FIN -> TH_FIN
TCP_FLAG_PUSH -> TH_PUSH
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
hw/net/rtl8139.c | 35 ++++++++++++++---------------------
1 file changed, 14 insertions(+), 21 deletions(-)
diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c
index 6de94d9..36be22b 100644
--- a/hw/net/rtl8139.c
+++ b/hw/net/rtl8139.c
@@ -73,10 +73,8 @@
#define MOD2(input, size) \
( ( input ) & ( size - 1 ) )
-#define ETHER_ADDR_LEN 6
#define ETHER_TYPE_LEN 2
-#define ETH_HLEN (ETHER_ADDR_LEN * 2 + ETHER_TYPE_LEN)
-#define ETH_P_8021Q 0x8100 /* 802.1Q VLAN Extended Header */
+#define ETH_HLEN (ETH_ALEN * 2 + ETHER_TYPE_LEN)
#define ETH_MTU 1500
#define VLAN_TCI_LEN 2
@@ -1016,8 +1014,8 @@ static ssize_t rtl8139_do_receive(NetClientState *nc, const uint8_t *buf, size_t
/* write VLAN info to descriptor variables. */
if (s->CpCmd & CPlusRxVLAN && be16_to_cpup((uint16_t *)
- &buf[ETHER_ADDR_LEN * 2]) == ETH_P_8021Q) {
- dot1q_buf = &buf[ETHER_ADDR_LEN * 2];
+ &buf[ETH_ALEN * 2]) == ETH_P_VLAN) {
+ dot1q_buf = &buf[ETH_ALEN * 2];
size -= VLAN_HLEN;
/* if too small buffer, use the tailroom added duing expansion */
if (size < MIN_BUF_SIZE) {
@@ -1058,10 +1056,10 @@ static ssize_t rtl8139_do_receive(NetClientState *nc, const uint8_t *buf, size_t
/* receive/copy to target memory */
if (dot1q_buf) {
- pci_dma_write(d, rx_addr, buf, 2 * ETHER_ADDR_LEN);
- pci_dma_write(d, rx_addr + 2 * ETHER_ADDR_LEN,
- buf + 2 * ETHER_ADDR_LEN + VLAN_HLEN,
- size - 2 * ETHER_ADDR_LEN);
+ pci_dma_write(d, rx_addr, buf, 2 * ETH_ALEN);
+ pci_dma_write(d, rx_addr + 2 * ETH_ALEN,
+ buf + 2 * ETH_ALEN + VLAN_HLEN,
+ size - 2 * ETH_ALEN);
} else {
pci_dma_write(d, rx_addr, buf, size);
}
@@ -1783,12 +1781,12 @@ static void rtl8139_transfer_frame(RTL8139State *s, uint8_t *buf, int size,
return;
}
- if (dot1q_buf && size >= ETHER_ADDR_LEN * 2) {
+ if (dot1q_buf && size >= ETH_ALEN * 2) {
iov = (struct iovec[3]) {
- { .iov_base = buf, .iov_len = ETHER_ADDR_LEN * 2 },
+ { .iov_base = buf, .iov_len = ETH_ALEN * 2 },
{ .iov_base = (void *) dot1q_buf, .iov_len = VLAN_HLEN },
- { .iov_base = buf + ETHER_ADDR_LEN * 2,
- .iov_len = size - ETHER_ADDR_LEN * 2 },
+ { .iov_base = buf + ETH_ALEN * 2,
+ .iov_len = size - ETH_ALEN * 2 },
};
memcpy(vlan_iov, iov, sizeof(vlan_iov));
@@ -1868,17 +1866,12 @@ static int rtl8139_transmit_one(RTL8139State *s, int descriptor)
}
/* structures and macros for task offloading */
-#define IP_HEADER_LENGTH(ip) (((ip->ip_ver_len)&0xf) << 2)
-
#define TCP_HEADER_DATA_OFFSET(tcp) (((be16_to_cpu(tcp->th_offset_flags) >> 12)&0xf) << 2)
#define TCP_FLAGS_ONLY(flags) ((flags)&0x3f)
#define TCP_HEADER_FLAGS(tcp) TCP_FLAGS_ONLY(be16_to_cpu(tcp->th_offset_flags))
#define TCP_HEADER_CLEAR_FLAGS(tcp, off) ((tcp)->th_offset_flags &= cpu_to_be16(~TCP_FLAGS_ONLY(off)))
-#define TCP_FLAG_FIN 0x01
-#define TCP_FLAG_PUSH 0x08
-
/* produces ones' complement sum of data */
static uint16_t ones_complement_sum(uint8_t *data, size_t len)
{
@@ -2087,7 +2080,7 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
bswap16(txdw1 & CP_TX_VLAN_TAG_MASK));
dot1q_buffer = (uint16_t *) dot1q_buffer_space;
- dot1q_buffer[0] = cpu_to_be16(ETH_P_8021Q);
+ dot1q_buffer[0] = cpu_to_be16(ETH_P_VLAN);
/* BE + le_to_cpu() + ~cpu_to_le()~ = BE */
dot1q_buffer[1] = cpu_to_le16(txdw1 & CP_TX_VLAN_TAG_MASK);
} else {
@@ -2138,7 +2131,7 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
goto skip_offload;
}
- hlen = IP_HEADER_LENGTH(ip);
+ hlen = IP_HDR_GET_LEN(ip);
if (hlen < sizeof(struct ip_header) || hlen > eth_payload_len) {
goto skip_offload;
}
@@ -2240,7 +2233,7 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
/* keep PUSH and FIN flags only for the last frame */
if (!is_last_frame)
{
- TCP_HEADER_CLEAR_FLAGS(p_tcp_hdr, TCP_FLAG_PUSH|TCP_FLAG_FIN);
+ TCP_HEADER_CLEAR_FLAGS(p_tcp_hdr, TH_PUSH | TH_FIN);
}
/* recalculate TCP checksum */
--
2.4.3
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [Qemu-devel] [PATCH 3/3] rtl8139: use ldl/stl wrapper for unaligned 32-bit access
2015-08-03 12:15 [Qemu-devel] [PATCH 0/3] rtl8139: cleanups Stefan Hajnoczi
2015-08-03 12:15 ` [Qemu-devel] [PATCH 1/3] rtl8139: remove duplicate net/eth.h definitions Stefan Hajnoczi
2015-08-03 12:15 ` [Qemu-devel] [PATCH 2/3] rtl8139: use net/eth.h macros instead of custom macros Stefan Hajnoczi
@ 2015-08-03 12:15 ` Stefan Hajnoczi
2015-08-04 5:11 ` [Qemu-devel] [PATCH 0/3] rtl8139: cleanups Jason Wang
2015-08-26 12:13 ` Stefan Hajnoczi
4 siblings, 0 replies; 6+ messages in thread
From: Stefan Hajnoczi @ 2015-08-03 12:15 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell, jasowang, Stefan Hajnoczi
The tx offload feature accesses a 16-bit aligned TCP header struct. The
32-bit fields must be accessed using ldl/stl wrappers since some host
architectures fault on unaligned access.
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
hw/net/rtl8139.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c
index 36be22b..366d1b5 100644
--- a/hw/net/rtl8139.c
+++ b/hw/net/rtl8139.c
@@ -2118,7 +2118,11 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
DPRINTF("+++ C+ mode has IP packet\n");
- /* not aligned */
+ /* Note on memory alignment: eth_payload_data is 16-bit aligned
+ * since saved_buffer is allocated with g_malloc() and ETH_HLEN is
+ * even. 32-bit accesses must use ldl/stl wrappers to avoid
+ * unaligned accesses.
+ */
eth_payload_data = saved_buffer + ETH_HLEN;
eth_payload_len = saved_size - ETH_HLEN;
@@ -2215,7 +2219,7 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
}
DPRINTF("+++ C+ mode TSO TCP seqno %08x\n",
- be32_to_cpu(p_tcp_hdr->th_seq));
+ ldl_be_p(&p_tcp_hdr->th_seq));
/* add 4 TCP pseudoheader fields */
/* copy IP source and destination fields */
@@ -2271,7 +2275,8 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
0, (uint8_t *) dot1q_buffer);
/* add transferred count to TCP sequence number */
- p_tcp_hdr->th_seq = cpu_to_be32(chunk_size + be32_to_cpu(p_tcp_hdr->th_seq));
+ stl_be_p(&p_tcp_hdr->th_seq,
+ chunk_size + ldl_be_p(&p_tcp_hdr->th_seq));
++send_count;
}
--
2.4.3
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [Qemu-devel] [PATCH 0/3] rtl8139: cleanups
2015-08-03 12:15 [Qemu-devel] [PATCH 0/3] rtl8139: cleanups Stefan Hajnoczi
` (2 preceding siblings ...)
2015-08-03 12:15 ` [Qemu-devel] [PATCH 3/3] rtl8139: use ldl/stl wrapper for unaligned 32-bit access Stefan Hajnoczi
@ 2015-08-04 5:11 ` Jason Wang
2015-08-26 12:13 ` Stefan Hajnoczi
4 siblings, 0 replies; 6+ messages in thread
From: Jason Wang @ 2015-08-04 5:11 UTC (permalink / raw)
To: Stefan Hajnoczi, qemu-devel; +Cc: Peter Maydell
On 08/03/2015 08:15 PM, Stefan Hajnoczi wrote:
> After addressing CVE-2015-5165 there were several additional rtl8139 cleanups
> that I'm sending separately since they are not security fixes.
>
> These patches eliminate duplicate eth.h structs/macros and fix unaligned memory
> accesses in tx offload.
>
> Stefan Hajnoczi (3):
> rtl8139: remove duplicate net/eth.h definitions
> rtl8139: use net/eth.h macros instead of custom macros
> rtl8139: use ldl/stl wrapper for unaligned 32-bit access
>
> hw/net/rtl8139.c | 103 +++++++++++++++----------------------------------------
> 1 file changed, 27 insertions(+), 76 deletions(-)
>
Reviewed-by: Jason Wang <jasowang@redhat.com>
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [Qemu-devel] [PATCH 0/3] rtl8139: cleanups
2015-08-03 12:15 [Qemu-devel] [PATCH 0/3] rtl8139: cleanups Stefan Hajnoczi
` (3 preceding siblings ...)
2015-08-04 5:11 ` [Qemu-devel] [PATCH 0/3] rtl8139: cleanups Jason Wang
@ 2015-08-26 12:13 ` Stefan Hajnoczi
4 siblings, 0 replies; 6+ messages in thread
From: Stefan Hajnoczi @ 2015-08-26 12:13 UTC (permalink / raw)
To: Stefan Hajnoczi; +Cc: Peter Maydell, jasowang, qemu-devel
On Mon, Aug 03, 2015 at 01:15:54PM +0100, Stefan Hajnoczi wrote:
> After addressing CVE-2015-5165 there were several additional rtl8139 cleanups
> that I'm sending separately since they are not security fixes.
>
> These patches eliminate duplicate eth.h structs/macros and fix unaligned memory
> accesses in tx offload.
>
> Stefan Hajnoczi (3):
> rtl8139: remove duplicate net/eth.h definitions
> rtl8139: use net/eth.h macros instead of custom macros
> rtl8139: use ldl/stl wrapper for unaligned 32-bit access
>
> hw/net/rtl8139.c | 103 +++++++++++++++----------------------------------------
> 1 file changed, 27 insertions(+), 76 deletions(-)
>
> --
> 2.4.3
>
>
Thanks, applied to my net tree:
https://github.com/stefanha/qemu/commits/net
Stefan
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2015-08-26 12:13 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-08-03 12:15 [Qemu-devel] [PATCH 0/3] rtl8139: cleanups Stefan Hajnoczi
2015-08-03 12:15 ` [Qemu-devel] [PATCH 1/3] rtl8139: remove duplicate net/eth.h definitions Stefan Hajnoczi
2015-08-03 12:15 ` [Qemu-devel] [PATCH 2/3] rtl8139: use net/eth.h macros instead of custom macros Stefan Hajnoczi
2015-08-03 12:15 ` [Qemu-devel] [PATCH 3/3] rtl8139: use ldl/stl wrapper for unaligned 32-bit access Stefan Hajnoczi
2015-08-04 5:11 ` [Qemu-devel] [PATCH 0/3] rtl8139: cleanups Jason Wang
2015-08-26 12:13 ` Stefan Hajnoczi
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).