From c6a33e2464edd87f8c12cc2d11369a5b44c65b77 Mon Sep 17 00:00:00 2001 From: Albert Lee Date: Wed, 12 Oct 2005 15:12:26 +0800 Subject: [PATCH] libata CHS: LBA28/LBA48 optimization (revise #6) - add lba_28_ok() and lba_48_ok() to ata.h. - check ending block number instead of staring block number. - use lba_28_ok() for CHS range check - LBA28/LBA48 optimization Suggested by Mark Lord and Alan Cox. Signed-off-by: Albert Lee ===== Signed-off-by: Jeff Garzik --- include/linux/ata.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'include') diff --git a/include/linux/ata.h b/include/linux/ata.h index 630908c937..b7e7e1cb26 100644 --- a/include/linux/ata.h +++ b/include/linux/ata.h @@ -291,4 +291,16 @@ static inline int ata_ok(u8 status) == ATA_DRDY); } +static inline int lba_28_ok(u64 block, u32 n_block) +{ + /* check the ending block number */ + return ((block + n_block - 1) < ((u64)1 << 28)) && (n_block <= 256); +} + +static inline int lba_48_ok(u64 block, u32 n_block) +{ + /* check the ending block number */ + return ((block + n_block - 1) < ((u64)1 << 48)) && (n_block <= 65536); +} + #endif /* __LINUX_ATA_H__ */ -- cgit v1.2.2 From f03aa2d89ad600a1ed21a223f196776f217cfe00 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Sat, 14 Jan 2006 03:10:22 +0100 Subject: [PATCH] drivers/net/arcnet/: possible cleanups This patch contains the following possible cleanups: - make needlessly global code static - arcnet.c: remove the unneeded EXPORT_SYMBOL(arc_proto_null) - arcnet.c: remove the unneeded EXPORT_SYMBOL(arcnet_dump_packet) To make Jeff happy, arcnet.c still prints arcnet: v3.93 BETA 2000/04/29 - by Avery Pennarun et al. Signed-off-by: Adrian Bunk Signed-off-by: Jeff Garzik --- include/linux/arcdevice.h | 9 --------- 1 file changed, 9 deletions(-) (limited to 'include') diff --git a/include/linux/arcdevice.h b/include/linux/arcdevice.h index 7198f129e1..231ba090ae 100644 --- a/include/linux/arcdevice.h +++ b/include/linux/arcdevice.h @@ -206,7 +206,6 @@ struct ArcProto { extern struct ArcProto *arc_proto_map[256], *arc_proto_default, *arc_bcast_proto, *arc_raw_proto; -extern struct ArcProto arc_proto_null; /* @@ -334,17 +333,9 @@ void arcnet_dump_skb(struct net_device *dev, struct sk_buff *skb, char *desc); #define arcnet_dump_skb(dev,skb,desc) ; #endif -#if (ARCNET_DEBUG_MAX & D_RX) || (ARCNET_DEBUG_MAX & D_TX) -void arcnet_dump_packet(struct net_device *dev, int bufnum, char *desc, - int take_arcnet_lock); -#else -#define arcnet_dump_packet(dev, bufnum, desc,take_arcnet_lock) ; -#endif - void arcnet_unregister_proto(struct ArcProto *proto); irqreturn_t arcnet_interrupt(int irq, void *dev_id, struct pt_regs *regs); struct net_device *alloc_arcdev(char *name); -void arcnet_rx(struct net_device *dev, int bufnum); #endif /* __KERNEL__ */ #endif /* _LINUX_ARCDEVICE_H */ -- cgit v1.2.2 From bfd6057959ecd3ff779a373a4d07cda2c2d0eec1 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Tue, 17 Jan 2006 19:34:42 -0500 Subject: From: Borislav Petkov libata new debugging macro definitions Signed-off-by: Borislav Petkov Signed-off-by: Randy Dunlap --- include/linux/libata.h | 52 +++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 45 insertions(+), 7 deletions(-) (limited to 'include') diff --git a/include/linux/libata.h b/include/linux/libata.h index a43c95f8f9..339f7e75cb 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -35,7 +35,8 @@ #include /* - * compile-time options + * compile-time options: to be removed as soon as all the drivers are + * converted to the new debugging mechanism */ #undef ATA_DEBUG /* debugging output */ #undef ATA_VERBOSE_DEBUG /* yet more debugging output */ @@ -71,6 +72,38 @@ } #endif +/* NEW: debug levels */ +#define HAVE_LIBATA_MSG 1 + +enum { + ATA_MSG_DRV = 0x0001, + ATA_MSG_INFO = 0x0002, + ATA_MSG_PROBE = 0x0004, + ATA_MSG_WARN = 0x0008, + ATA_MSG_MALLOC = 0x0010, + ATA_MSG_CTL = 0x0020, + ATA_MSG_INTR = 0x0040, + ATA_MSG_ERR = 0x0080, +}; + +#define ata_msg_drv(p) ((p)->msg_enable & ATA_MSG_DRV) +#define ata_msg_info(p) ((p)->msg_enable & ATA_MSG_INFO) +#define ata_msg_probe(p) ((p)->msg_enable & ATA_MSG_PROBE) +#define ata_msg_warn(p) ((p)->msg_enable & ATA_MSG_WARN) +#define ata_msg_malloc(p) ((p)->msg_enable & ATA_MSG_MALLOC) +#define ata_msg_ctl(p) ((p)->msg_enable & ATA_MSG_CTL) +#define ata_msg_intr(p) ((p)->msg_enable & ATA_MSG_INTR) +#define ata_msg_err(p) ((p)->msg_enable & ATA_MSG_ERR) + +static inline u32 ata_msg_init(int dval, int default_msg_enable_bits) +{ + if (dval < 0 || dval >= (sizeof(u32) * 8)) + return default_msg_enable_bits; /* should be 0x1 - only driver info msgs */ + if (!dval) + return 0; + return (1 << dval) - 1; +} + /* defines only for the constants which don't work well as enums */ #define ATA_TAG_POISON 0xfafbfcfdU @@ -356,6 +389,8 @@ struct ata_port { unsigned int hsm_task_state; unsigned long pio_task_timeout; + u32 msg_enable; + void *private_data; }; @@ -640,9 +675,9 @@ static inline u8 ata_wait_idle(struct ata_port *ap) if (status & (ATA_BUSY | ATA_DRQ)) { unsigned long l = ap->ioaddr.status_addr; - printk(KERN_WARNING - "ATA: abnormal status 0x%X on port 0x%lX\n", - status, l); + if (ata_msg_warn(ap)) + printk(KERN_WARNING "ATA: abnormal status 0x%X on port 0x%lX\n", + status, l); } return status; @@ -734,7 +769,8 @@ static inline u8 ata_irq_ack(struct ata_port *ap, unsigned int chk_drq) status = ata_busy_wait(ap, bits, 1000); if (status & bits) - DPRINTK("abnormal status 0x%X\n", status); + if (ata_msg_err(ap)) + printk(KERN_ERR "abnormal status 0x%X\n", status); /* get controller status; clear intr, err bits */ if (ap->flags & ATA_FLAG_MMIO) { @@ -752,8 +788,10 @@ static inline u8 ata_irq_ack(struct ata_port *ap, unsigned int chk_drq) post_stat = inb(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS); } - VPRINTK("irq ack: host_stat 0x%X, new host_stat 0x%X, drv_stat 0x%X\n", - host_stat, post_stat, status); + if (ata_msg_intr(ap)) + printk(KERN_INFO "%s: irq ack: host_stat 0x%X, new host_stat 0x%X, drv_stat 0x%X\n", + __FUNCTION__, + host_stat, post_stat, status); return status; } -- cgit v1.2.2 From 4c0f631e14b849782259519c749414b1f1ddbfa8 Mon Sep 17 00:00:00 2001 From: Ricardo Cerqueira Date: Mon, 23 Jan 2006 09:42:06 -0200 Subject: V4L/DVB (3393): Move all IR keymaps to ir-common module - All the keymaps have the same structure, and can be shared between different chips, so it makes no sense having them scattered between the input files. This aggregates them all at ir-common module. - Added new Hauppauge remote (Hauppauge grey), contributed by J.O. Aho (with some small changes) Changed KEY_KPx (keypad numerals) references to KEY_x, to avoid problems when NumLock is off (suggested by Peter Missel ) - Some cleanups at IR code Signed-off-by: Ricardo Cerqueira Signed-off-by: Mauro Carvalho Chehab --- include/media/ir-common.h | 42 +++++++++++++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 7 deletions(-) (limited to 'include') diff --git a/include/media/ir-common.h b/include/media/ir-common.h index ad3e9bb670..50fe522bad 100644 --- a/include/media/ir-common.h +++ b/include/media/ir-common.h @@ -47,13 +47,6 @@ struct ir_input_state { int keypressed; /* current state */ }; -extern IR_KEYTAB_TYPE ir_codes_rc5_tv[IR_KEYTAB_SIZE]; -extern IR_KEYTAB_TYPE ir_codes_winfast[IR_KEYTAB_SIZE]; -extern IR_KEYTAB_TYPE ir_codes_pinnacle[IR_KEYTAB_SIZE]; -extern IR_KEYTAB_TYPE ir_codes_empty[IR_KEYTAB_SIZE]; -extern IR_KEYTAB_TYPE ir_codes_hauppauge_new[IR_KEYTAB_SIZE]; -extern IR_KEYTAB_TYPE ir_codes_pixelview[IR_KEYTAB_SIZE]; - void ir_input_init(struct input_dev *dev, struct ir_input_state *ir, int ir_type, IR_KEYTAB_TYPE *ir_codes); void ir_input_nokey(struct input_dev *dev, struct ir_input_state *ir); @@ -64,6 +57,41 @@ int ir_dump_samples(u32 *samples, int count); int ir_decode_biphase(u32 *samples, int count, int low, int high); int ir_decode_pulsedistance(u32 *samples, int count, int low, int high); +/* Keymaps to be used by other modules */ + +extern IR_KEYTAB_TYPE ir_codes_empty[IR_KEYTAB_SIZE]; +extern IR_KEYTAB_TYPE ir_codes_avermedia[IR_KEYTAB_SIZE]; +extern IR_KEYTAB_TYPE ir_codes_avermedia_dvbt[IR_KEYTAB_SIZE]; +extern IR_KEYTAB_TYPE ir_codes_apac_viewcomp[IR_KEYTAB_SIZE]; +extern IR_KEYTAB_TYPE ir_codes_conceptronic[IR_KEYTAB_SIZE]; +extern IR_KEYTAB_TYPE ir_codes_nebula[IR_KEYTAB_SIZE]; +extern IR_KEYTAB_TYPE ir_codes_dntv_live_dvb_t[IR_KEYTAB_SIZE]; +extern IR_KEYTAB_TYPE ir_codes_iodata_bctv7e[IR_KEYTAB_SIZE]; +extern IR_KEYTAB_TYPE ir_codes_adstech_dvb_t_pci[IR_KEYTAB_SIZE]; +extern IR_KEYTAB_TYPE ir_codes_msi_tvanywhere[IR_KEYTAB_SIZE]; +extern IR_KEYTAB_TYPE ir_codes_cinergy_1400[IR_KEYTAB_SIZE]; +extern IR_KEYTAB_TYPE ir_codes_avertv_303[IR_KEYTAB_SIZE]; +extern IR_KEYTAB_TYPE ir_codes_dntv_live_dvbt_pro[IR_KEYTAB_SIZE]; +extern IR_KEYTAB_TYPE ir_codes_em_terratec[IR_KEYTAB_SIZE]; +extern IR_KEYTAB_TYPE ir_codes_em_pinnacle_usb[IR_KEYTAB_SIZE]; +extern IR_KEYTAB_TYPE ir_codes_flyvideo[IR_KEYTAB_SIZE]; +extern IR_KEYTAB_TYPE ir_codes_flydvb[IR_KEYTAB_SIZE]; +extern IR_KEYTAB_TYPE ir_codes_cinergy[IR_KEYTAB_SIZE]; +extern IR_KEYTAB_TYPE ir_codes_eztv[IR_KEYTAB_SIZE]; +extern IR_KEYTAB_TYPE ir_codes_avacssmart[IR_KEYTAB_SIZE]; +extern IR_KEYTAB_TYPE ir_codes_md2819[IR_KEYTAB_SIZE]; +extern IR_KEYTAB_TYPE ir_codes_videomate_tv_pvr[IR_KEYTAB_SIZE]; +extern IR_KEYTAB_TYPE ir_codes_manli[IR_KEYTAB_SIZE]; +extern IR_KEYTAB_TYPE ir_codes_gotview7135[IR_KEYTAB_SIZE]; +extern IR_KEYTAB_TYPE ir_codes_purpletv[IR_KEYTAB_SIZE]; +extern IR_KEYTAB_TYPE ir_codes_pctv_sedna[IR_KEYTAB_SIZE]; +extern IR_KEYTAB_TYPE ir_codes_pv951[IR_KEYTAB_SIZE]; +extern IR_KEYTAB_TYPE ir_codes_rc5_tv[IR_KEYTAB_SIZE]; +extern IR_KEYTAB_TYPE ir_codes_winfast[IR_KEYTAB_SIZE]; +extern IR_KEYTAB_TYPE ir_codes_pinnacle[IR_KEYTAB_SIZE]; +extern IR_KEYTAB_TYPE ir_codes_hauppauge_new[IR_KEYTAB_SIZE]; +extern IR_KEYTAB_TYPE ir_codes_pixelview[IR_KEYTAB_SIZE]; + #endif /* -- cgit v1.2.2 From b639f9d286f2216795492eac2a39b8ed6b4d555c Mon Sep 17 00:00:00 2001 From: "Nickolay V. Shmyrev" Date: Mon, 23 Jan 2006 09:44:10 -0200 Subject: V4L/DVB (3400): Remove duplicated keymaps and add keymap for KWorld LTV883IR. - Remove duplicated keymaps and add keymap for KWorld LTV883IR. Thanks to Jon Ferguson . Signed-off-by: Nickolay V. Shmyrev Signed-off-by: Mauro Carvalho Chehab --- include/media/ir-common.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/media/ir-common.h b/include/media/ir-common.h index 50fe522bad..302d5b3946 100644 --- a/include/media/ir-common.h +++ b/include/media/ir-common.h @@ -63,7 +63,7 @@ extern IR_KEYTAB_TYPE ir_codes_empty[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_avermedia[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_avermedia_dvbt[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_apac_viewcomp[IR_KEYTAB_SIZE]; -extern IR_KEYTAB_TYPE ir_codes_conceptronic[IR_KEYTAB_SIZE]; +extern IR_KEYTAB_TYPE ir_codes_pixelview[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_nebula[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_dntv_live_dvb_t[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_iodata_bctv7e[IR_KEYTAB_SIZE]; @@ -78,8 +78,7 @@ extern IR_KEYTAB_TYPE ir_codes_flyvideo[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_flydvb[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_cinergy[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_eztv[IR_KEYTAB_SIZE]; -extern IR_KEYTAB_TYPE ir_codes_avacssmart[IR_KEYTAB_SIZE]; -extern IR_KEYTAB_TYPE ir_codes_md2819[IR_KEYTAB_SIZE]; +extern IR_KEYTAB_TYPE ir_codes_avermedia[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_videomate_tv_pvr[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_manli[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_gotview7135[IR_KEYTAB_SIZE]; @@ -90,7 +89,6 @@ extern IR_KEYTAB_TYPE ir_codes_rc5_tv[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_winfast[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_pinnacle[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_hauppauge_new[IR_KEYTAB_SIZE]; -extern IR_KEYTAB_TYPE ir_codes_pixelview[IR_KEYTAB_SIZE]; #endif -- cgit v1.2.2 From 6ac48b458769059ee6147dd8bf2767e820407292 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 23 Jan 2006 17:11:05 -0200 Subject: V4L/DVB (3408): Included new sliced VBI types to videodev2.h and tvp5150 - Added other sliced VBI types to videodev2.h - tvp5150 now uses standard V4L2 API codes from videodev2.h - Implemented VIDIOC_G_SLICED_VBI_CAP for tvp5150. This is dynamically filled based on defined VDP C-RAM values filled by the driver. Signed-off-by: Mauro Carvalho Chehab --- include/linux/videodev2.h | 51 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 44 insertions(+), 7 deletions(-) (limited to 'include') diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index ce40675324..27ae3d679c 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h @@ -949,13 +949,50 @@ struct v4l2_sliced_vbi_format __u32 reserved[2]; /* must be zero */ }; -#define V4L2_SLICED_TELETEXT_B (0x0001) -#define V4L2_SLICED_VPS (0x0400) -#define V4L2_SLICED_CAPTION_525 (0x1000) -#define V4L2_SLICED_WSS_625 (0x4000) - -#define V4L2_SLICED_VBI_525 (V4L2_SLICED_CAPTION_525) -#define V4L2_SLICED_VBI_625 (V4L2_SLICED_TELETEXT_B | V4L2_SLICED_VPS | V4L2_SLICED_WSS_625) +/* Teletext WST, defined on ITU-R BT.653-2 */ +#define V4L2_SLICED_TELETEXT_PAL_B (0x000001) +#define V4L2_SLICED_TELETEXT_PAL_C (0x000002) +#define V4L2_SLICED_TELETEXT_NTSC_B (0x000010) +#define V4L2_SLICED_TELETEXT_SECAM (0x000020) + +/* Teletext NABTS, defined on ITU-R BT.653-2 */ +#define V4L2_SLICED_TELETEXT_NTSC_C (0x000040) +#define V4L2_SLICED_TELETEXT_NTSC_D (0x000080) + +/* Video Program System, defined on ETS 300 231*/ +#define V4L2_SLICED_VPS (0x000400) + +/* Closed Caption, defined on EIA-608 */ +#define V4L2_SLICED_CAPTION_525 (0x001000) +#define V4L2_SLICED_CAPTION_625 (0x002000) + +/* Wide Screen System, defined on ITU-R BT1119.1 */ +#define V4L2_SLICED_WSS_625 (0x004000) + +/* Wide Screen System, defined on IEC 61880 */ +#define V4L2_SLICED_WSS_525 (0x008000) + +/* Vertical Interval Timecode (VITC), defined on SMPTE 12M */ +#define V4l2_SLICED_VITC_625 (0x010000) +#define V4l2_SLICED_VITC_525 (0x020000) + +/* Compat macro - Should be removed for 2.6.18 */ +#define V4L2_SLICED_TELETEXT_B V4L2_SLICED_TELETEXT_PAL_B + +#define V4L2_SLICED_VBI_525 (V4L2_SLICED_TELETEXT_NTSC_B |\ + V4L2_SLICED_TELETEXT_NTSC_C |\ + V4L2_SLICED_TELETEXT_NTSC_D |\ + V4L2_SLICED_CAPTION_525 |\ + V4L2_SLICED_WSS_525 |\ + V4l2_SLICED_VITC_525) + +#define V4L2_SLICED_VBI_625 (V4L2_SLICED_TELETEXT_PAL_B |\ + V4L2_SLICED_TELETEXT_PAL_C |\ + V4L2_SLICED_TELETEXT_SECAM |\ + V4L2_SLICED_VPS |\ + V4L2_SLICED_CAPTION_625 |\ + V4L2_SLICED_WSS_625 |\ + V4l2_SLICED_VITC_625) struct v4l2_sliced_vbi_cap { -- cgit v1.2.2 From 4d0dddb10723cee2b3048bd2389673703bc228e4 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 23 Jan 2006 17:11:07 -0200 Subject: V4L/DVB (3419): added some VBI macros and moved minor definitions to header file - Moved some hardcoded minor numbers to videodev2.h - Included more comments for sliced VBI standards - Included some VBI macros to group similar standards Signed-off-by: Mauro Carvalho Chehab --- include/linux/videodev2.h | 38 +++++++++++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 5 deletions(-) (limited to 'include') diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index 27ae3d679c..6e33ce96ca 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h @@ -21,7 +21,7 @@ #include /* need __user */ -#define OBSOLETE_OWNER 1 /* It will be removed for 2.6.15 */ +#define OBSOLETE_OWNER 1 /* It will be removed for 2.6.17 */ #define HAVE_V4L2 1 /* @@ -48,6 +48,16 @@ #ifdef __KERNEL__ +/* Minor device allocation */ +#define MINOR_VFL_TYPE_GRABBER_MIN 0 +#define MINOR_VFL_TYPE_GRABBER_MAX 63 +#define MINOR_VFL_TYPE_RADIO_MIN 64 +#define MINOR_VFL_TYPE_RADIO_MAX 127 +#define MINOR_VFL_TYPE_VTX_MIN 192 +#define MINOR_VFL_TYPE_VTX_MAX 223 +#define MINOR_VFL_TYPE_VBI_MIN 224 +#define MINOR_VFL_TYPE_VBI_MAX 255 + #define VFL_TYPE_GRABBER 0 #define VFL_TYPE_VBI 1 #define VFL_TYPE_RADIO 2 @@ -949,13 +959,15 @@ struct v4l2_sliced_vbi_format __u32 reserved[2]; /* must be zero */ }; -/* Teletext WST, defined on ITU-R BT.653-2 */ +/* Teletext World System Teletext + (WST), defined on ITU-R BT.653-2 */ #define V4L2_SLICED_TELETEXT_PAL_B (0x000001) #define V4L2_SLICED_TELETEXT_PAL_C (0x000002) #define V4L2_SLICED_TELETEXT_NTSC_B (0x000010) #define V4L2_SLICED_TELETEXT_SECAM (0x000020) -/* Teletext NABTS, defined on ITU-R BT.653-2 */ +/* Teletext North American Broadcast Teletext Specification + (NABTS), defined on ITU-R BT.653-2 */ #define V4L2_SLICED_TELETEXT_NTSC_C (0x000040) #define V4L2_SLICED_TELETEXT_NTSC_D (0x000080) @@ -976,8 +988,24 @@ struct v4l2_sliced_vbi_format #define V4l2_SLICED_VITC_625 (0x010000) #define V4l2_SLICED_VITC_525 (0x020000) -/* Compat macro - Should be removed for 2.6.18 */ -#define V4L2_SLICED_TELETEXT_B V4L2_SLICED_TELETEXT_PAL_B +#define V4L2_SLICED_TELETEXT_B (V4L2_SLICED_TELETEXT_PAL_B |\ + V4L2_SLICED_TELETEXT_NTSC_B) + +#define V4L2_SLICED_TELETEXT (V4L2_SLICED_TELETEXT_PAL_B |\ + V4L2_SLICED_TELETEXT_PAL_C |\ + V4L2_SLICED_TELETEXT_SECAM |\ + V4L2_SLICED_TELETEXT_NTSC_B |\ + V4L2_SLICED_TELETEXT_NTSC_C |\ + V4L2_SLICED_TELETEXT_NTSC_D) + +#define V4L2_SLICED_CAPTION (V4L2_SLICED_CAPTION_525 |\ + V4L2_SLICED_CAPTION_625) + +#define V4L2_SLICED_WSS (V4L2_SLICED_WSS_525 |\ + V4L2_SLICED_WSS_625) + +#define V4L2_SLICED_VITC (V4L2_SLICED_VITC_525 |\ + V4L2_SLICED_VITC_625) #define V4L2_SLICED_VBI_525 (V4L2_SLICED_TELETEXT_NTSC_B |\ V4L2_SLICED_TELETEXT_NTSC_C |\ -- cgit v1.2.2 From 12db56071b473a59c550d0aa70db6972a49d73af Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 23 Jan 2006 17:11:08 -0200 Subject: V4L/DVB (3420): Added iocls to configure VBI on tvp5150 - Added iocls to configure VBI on tvp5150 Signed-off-by: Mauro Carvalho Chehab --- include/media/v4l2-common.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h index d4030a7e16..11728daf00 100644 --- a/include/media/v4l2-common.h +++ b/include/media/v4l2-common.h @@ -160,7 +160,8 @@ struct msp_matrix { /* Used to generate VBI signals on a video signal. v4l2_sliced_vbi_data is filled with the data packets that should be output. Note that if you set - the line field to 0, then that VBI signal is disabled. */ + the line field to 0, then that VBI signal is disabled. If no + valid VBI data was found, then the type field is set to 0 on return. */ #define VIDIOC_INT_S_VBI_DATA _IOW ('d', 105, struct v4l2_sliced_vbi_data) /* Used to obtain the sliced VBI packet from a readback register. Not all -- cgit v1.2.2 From 757d250518c4905c5d13c8974446e08a2e3cf244 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 23 Jan 2006 17:11:10 -0200 Subject: V4L/DVB (3430): Add new internal VIDIOC_INT commands - Add new internal VIDIOC_INT commands for setting the tuner mode, for putting a chip into standby mode and to set/get the routing of inputs/outputs of audio or video of a chip. These new commands will replace older commands that are no longer up to the task. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/media/v4l2-common.h | 51 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 44 insertions(+), 7 deletions(-) (limited to 'include') diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h index 11728daf00..234e9cf7e8 100644 --- a/include/media/v4l2-common.h +++ b/include/media/v4l2-common.h @@ -115,12 +115,15 @@ enum v4l2_chip_ident { }; /* audio ioctls */ -/* v4l device was opened in Radio mode */ + +/* v4l device was opened in Radio mode, to be replaced by VIDIOC_INT_S_TUNER_MODE */ #define AUDC_SET_RADIO _IO('d',88) -/* select from TV,radio,extern,MUTE */ + +/* select from TV,radio,extern,MUTE, to be replaced with VIDIOC_INT_S_AUDIO_ROUTING */ #define AUDC_SET_INPUT _IOW('d',89,int) -/* msp3400 ioctl: will be removed in the near future */ +/* msp3400 ioctl: will be removed in the near future, to be replaced by + VIDIOC_INT_S_AUDIO_ROUTING. */ struct msp_matrix { int input; int output; @@ -128,12 +131,25 @@ struct msp_matrix { #define MSP_SET_MATRIX _IOW('m',17,struct msp_matrix) /* tuner ioctls */ + /* Sets tuner type and its I2C addr */ -#define TUNER_SET_TYPE_ADDR _IOW('d',90,int) -/* Puts tuner on powersaving state, disabling it, except for i2c */ -#define TUNER_SET_STANDBY _IOW('d',91,int) +#define TUNER_SET_TYPE_ADDR _IOW('d', 90, int) + +/* Puts tuner on powersaving state, disabling it, except for i2c. To be replaced + by VIDIOC_INT_S_STANDBY. */ +#define TUNER_SET_STANDBY _IOW('d', 91, int) + /* Sets tda9887 specific stuff, like port1, port2 and qss */ -#define TDA9887_SET_CONFIG _IOW('d',92,int) +#define TDA9887_SET_CONFIG _IOW('d', 92, int) + +/* Switch the tuner to a specific tuner mode. Replacement of AUDC_SET_RADIO */ +#define VIDIOC_INT_S_TUNER_MODE _IOW('d', 93, enum v4l2_tuner_type) + +/* Generic standby command. Passing -1 (all bits set to 1) will put the whole + chip into standby mode, value 0 will make the chip fully active. Specific + bits can be used by certain chips to enable/disable specific subsystems. + Replacement of TUNER_SET_STANDBY. */ +#define VIDIOC_INT_S_STANDBY _IOW('d', 94, u32) /* only implemented if CONFIG_VIDEO_ADV_DEBUG is defined */ #define VIDIOC_INT_S_REGISTER _IOR ('d', 100, struct v4l2_register) @@ -181,4 +197,25 @@ struct msp_matrix { If the frequency is not supported, then -EINVAL is returned. */ #define VIDIOC_INT_I2S_CLOCK_FREQ _IOW ('d', 108, u32) +/* Routing definition, device dependent. It specifies which inputs (if any) + should be routed to which outputs (if any). */ +struct v4l2_routing { + u32 input; + u32 output; +}; + +/* These internal commands should be used to define the inputs and outputs + of an audio/video chip. They will replace AUDC_SET_INPUT. + The v4l2 API commands VIDIOC_S/G_INPUT, VIDIOC_S/G_OUTPUT, + VIDIOC_S/G_AUDIO and VIDIOC_S/G_AUDOUT are meant to be used by the + user. Internally these commands should be used to switch inputs/outputs + because only the driver knows how to map a 'Television' input to the precise + input/output routing of an A/D converter, or a DSP, or a video digitizer. + These four commands should only be sent directly to an i2c device, they + should not be broadcast as the routing is very device specific. */ +#define VIDIOC_INT_S_AUDIO_ROUTING _IOW ('d', 109, struct v4l2_routing) +#define VIDIOC_INT_G_AUDIO_ROUTING _IOR ('d', 110, struct v4l2_routing *) +#define VIDIOC_INT_S_VIDEO_ROUTING _IOW ('d', 111, struct v4l2_routing) +#define VIDIOC_INT_G_VIDEO_ROUTING _IOR ('d', 112, struct v4l2_routing *) + #endif /* V4L2_COMMON_H_ */ -- cgit v1.2.2 From 3fc46d35b30cfae018c4903228a270c9543f4d7a Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Mon, 23 Jan 2006 17:11:11 -0200 Subject: V4L/DVB (3436): move config byte from tuner_params to tuner_range struct. - Move config byte from tuner_params to tuner_range struct. - dvb tuners must be able to set different config byte for each range. Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- include/media/tuner-types.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/media/tuner-types.h b/include/media/tuner-types.h index 15821ab14a..53ac66e011 100644 --- a/include/media/tuner-types.h +++ b/include/media/tuner-types.h @@ -14,6 +14,7 @@ enum param_type { struct tuner_range { unsigned short limit; + unsigned char config; unsigned char cb; }; @@ -38,7 +39,6 @@ struct tuner_params { * static unless the control byte was sent first. */ unsigned int cb_first_if_lower_freq:1; - unsigned char config; /* to be moved into struct tuner_range for dvb-pll merge */ unsigned int count; struct tuner_range *ranges; -- cgit v1.2.2 From 77853bf2b48e34449e826a9ef4df5ea0dbe947f4 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 23 Jan 2006 13:09:36 +0900 Subject: [PATCH] libata: make the owner of a qc responsible for freeing it qc used to be freed automatically on command completion. However, as a qc can carry information about its completion status, it can be useful to its owner/issuer after command completion. This patch makes freeing qc responsibility of its owner. This simplifies ata_exec_internal() and makes command turn-around for atapi request sensing less hackish. This change was originally suggested by Jeff Garzik. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- include/linux/libata.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/libata.h b/include/linux/libata.h index 46ccea2158..d58b659cf3 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -235,7 +235,7 @@ struct ata_port; struct ata_queued_cmd; /* typedefs */ -typedef int (*ata_qc_cb_t) (struct ata_queued_cmd *qc); +typedef void (*ata_qc_cb_t) (struct ata_queued_cmd *qc); struct ata_ioports { unsigned long cmd_addr; -- cgit v1.2.2 From 11a56d2439259892319df81cf1582687d7e7fde5 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 23 Jan 2006 13:09:36 +0900 Subject: [PATCH] libata: add detailed AC_ERR_* flags Add detailed AC_ERR_* flags and use them. Long-term goal is to describe all errors with err_mask and tf combination (tf for failed sector information, etc...). After proper error diagnosis is implemented, sense data should also be generated from err_mask instead of directly from hardware tf registers as it is currently. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- include/linux/libata.h | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'include') diff --git a/include/linux/libata.h b/include/linux/libata.h index d58b659cf3..8ff3a7f6f6 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -222,10 +222,15 @@ enum hsm_task_states { }; enum ata_completion_errors { - AC_ERR_OTHER = (1 << 0), - AC_ERR_DEV = (1 << 1), - AC_ERR_ATA_BUS = (1 << 2), - AC_ERR_HOST_BUS = (1 << 3), + AC_ERR_DEV = (1 << 0), /* device reported error */ + AC_ERR_HSM = (1 << 1), /* host state machine violation */ + AC_ERR_TIMEOUT = (1 << 2), /* timeout */ + AC_ERR_MEDIA = (1 << 3), /* media error */ + AC_ERR_ATA_BUS = (1 << 4), /* ATA bus error */ + AC_ERR_HOST_BUS = (1 << 5), /* host bus error */ + AC_ERR_SYSTEM = (1 << 6), /* system error */ + AC_ERR_INVALID = (1 << 7), /* invalid argument */ + AC_ERR_OTHER = (1 << 8), /* unknown */ }; /* forward declarations */ @@ -833,7 +838,7 @@ static inline int ata_try_flush_cache(const struct ata_device *dev) static inline unsigned int ac_err_mask(u8 status) { if (status & ATA_BUSY) - return AC_ERR_ATA_BUS; + return AC_ERR_HSM; if (status & (ATA_ERR | ATA_DF)) return AC_ERR_DEV; return 0; -- cgit v1.2.2 From 9a3d9eb0177eb10500d49cd283b35576082a522d Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 23 Jan 2006 13:09:36 +0900 Subject: [PATCH] libata: return AC_ERR_* from issue functions Return AC_ERR_* mask from issue fuctions instead of 0/-1. This enables things like failing a qc with AC_ERR_HSM when the device doesn't set DRDY when the qc is about to be issued. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- include/linux/libata.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/linux/libata.h b/include/linux/libata.h index 8ff3a7f6f6..b1ea2f98bf 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -427,7 +427,7 @@ struct ata_port_operations { void (*bmdma_start) (struct ata_queued_cmd *qc); void (*qc_prep) (struct ata_queued_cmd *qc); - int (*qc_issue) (struct ata_queued_cmd *qc); + unsigned int (*qc_issue) (struct ata_queued_cmd *qc); void (*eng_timeout) (struct ata_port *ap); @@ -515,7 +515,7 @@ extern void ata_port_stop (struct ata_port *ap); extern void ata_host_stop (struct ata_host_set *host_set); extern irqreturn_t ata_interrupt (int irq, void *dev_instance, struct pt_regs *regs); extern void ata_qc_prep(struct ata_queued_cmd *qc); -extern int ata_qc_issue_prot(struct ata_queued_cmd *qc); +extern unsigned int ata_qc_issue_prot(struct ata_queued_cmd *qc); extern void ata_sg_init_one(struct ata_queued_cmd *qc, void *buf, unsigned int buflen); extern void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg, -- cgit v1.2.2 From 041c5fc33cb7ed4fe5322585a611fb6e29a05d3a Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 23 Jan 2006 13:09:36 +0900 Subject: [PATCH] SCSI: export scsi_eh_finish_cmd() and scsi_eh_flush_done_q() Export two SCSI EH command handling functions. To be used by libata EH. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- include/scsi/scsi_eh.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include') diff --git a/include/scsi/scsi_eh.h b/include/scsi/scsi_eh.h index fabd879c2f..d160880b2a 100644 --- a/include/scsi/scsi_eh.h +++ b/include/scsi/scsi_eh.h @@ -35,6 +35,9 @@ static inline int scsi_sense_valid(struct scsi_sense_hdr *sshdr) } +extern void scsi_eh_finish_cmd(struct scsi_cmnd *scmd, + struct list_head *done_q); +extern void scsi_eh_flush_done_q(struct list_head *done_q); extern void scsi_report_bus_reset(struct Scsi_Host *, int); extern void scsi_report_device_reset(struct Scsi_Host *, int, int); extern int scsi_block_when_processing_errors(struct scsi_device *); -- cgit v1.2.2 From a72ec4ce6d3ae92e76baf5b2c65cc26e5e775e83 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 23 Jan 2006 13:09:37 +0900 Subject: [PATCH] libata: implement and apply ata_eh_qc_complete/retry() Implement ata_eh_qc_complete/retry() using scsi_eh_finish_cmd() and scsi_eh_flush_done_q(). This removes all eh scsicmd finish hacks from low level drivers. This change was first suggested by Jeff Garzik. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- include/linux/libata.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include') diff --git a/include/linux/libata.h b/include/linux/libata.h index b1ea2f98bf..576788de96 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -398,6 +398,7 @@ struct ata_port { unsigned long pio_task_timeout; u32 msg_enable; + struct list_head eh_done_q; void *private_data; }; @@ -490,6 +491,8 @@ extern int ata_scsi_detect(struct scsi_host_template *sht); extern int ata_scsi_ioctl(struct scsi_device *dev, int cmd, void __user *arg); extern int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)); extern int ata_scsi_error(struct Scsi_Host *host); +extern void ata_eh_qc_complete(struct ata_queued_cmd *qc); +extern void ata_eh_qc_retry(struct ata_queued_cmd *qc); extern int ata_scsi_release(struct Scsi_Host *host); extern unsigned int ata_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc); extern int ata_scsi_device_resume(struct scsi_device *); -- cgit v1.2.2 From 6f8b99589524f3e759e44721376abcdf88ed8915 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 24 Jan 2006 17:05:21 +0900 Subject: [PATCH] libata: export ata_busy_sleep Export ata_busy_sleep(), to be used by low level driver reset functions. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- include/linux/libata.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include') diff --git a/include/linux/libata.h b/include/linux/libata.h index 576788de96..45646f6ebb 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -500,6 +500,9 @@ extern int ata_scsi_device_suspend(struct scsi_device *); extern int ata_device_resume(struct ata_port *, struct ata_device *); extern int ata_device_suspend(struct ata_port *, struct ata_device *); extern int ata_ratelimit(void); +extern unsigned int ata_busy_sleep(struct ata_port *ap, + unsigned long timeout_pat, + unsigned long timeout); /* * Default driver ops implementations -- cgit v1.2.2 From c19ba8af4f104cca28d548cac55c128b28dd31fb Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 24 Jan 2006 17:05:22 +0900 Subject: [PATCH] libata: new ->probe_reset operation Add new ->probe_reset operation to ata_port_operations obsoleting ->phy_reset. The main difference from ->phy_reset is that the new operation is not allowed to manipulate libata internals directly. It's not allowed to configure or disable the port or devices. It can only succeed or fail and classify attached devices into passed @classes. This change gives more control to higher level and eases sharing reset methods with EH. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- include/linux/libata.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/linux/libata.h b/include/linux/libata.h index 45646f6ebb..a84d1c3a54 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -148,9 +148,9 @@ enum { ATA_FLAG_PORT_DISABLED = (1 << 2), /* port is disabled, ignore it */ ATA_FLAG_SATA = (1 << 3), ATA_FLAG_NO_LEGACY = (1 << 4), /* no legacy mode check */ - ATA_FLAG_SRST = (1 << 5), /* use ATA SRST, not E.D.D. */ + ATA_FLAG_SRST = (1 << 5), /* (obsolete) use ATA SRST, not E.D.D. */ ATA_FLAG_MMIO = (1 << 6), /* use MMIO, not PIO */ - ATA_FLAG_SATA_RESET = (1 << 7), /* use COMRESET */ + ATA_FLAG_SATA_RESET = (1 << 7), /* (obsolete) use COMRESET */ ATA_FLAG_PIO_DMA = (1 << 8), /* PIO cmds via DMA */ ATA_FLAG_NOINTR = (1 << 9), /* FIXME: Remove this once * proper HSM is in place. */ @@ -419,7 +419,9 @@ struct ata_port_operations { u8 (*check_altstatus)(struct ata_port *ap); void (*dev_select)(struct ata_port *ap, unsigned int device); - void (*phy_reset) (struct ata_port *ap); + void (*phy_reset) (struct ata_port *ap); /* obsolete */ + int (*probe_reset) (struct ata_port *ap, unsigned int *classes); + void (*post_set_mode) (struct ata_port *ap); int (*check_atapi_dma) (struct ata_queued_cmd *qc); -- cgit v1.2.2 From d0412d967032b9e147bcbacc9ff0c0342636cf2d Mon Sep 17 00:00:00 2001 From: James Chapman Date: Fri, 27 Jan 2006 01:15:30 -0700 Subject: [PATCH] mv643xx_eth: use MII library for ethtool functions Use the common ethtool support functions of the MII library. Add generic MII ioctl handler. Add PHY parameter speed/duplex/negotiation initialization and modification. Signed-off-by: James Chapman Signed-off-by: Dale Farnsworth Signed-off-by: Jeff Garzik --- include/linux/mv643xx.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include') diff --git a/include/linux/mv643xx.h b/include/linux/mv643xx.h index 0b08cd6922..7ffbeac7d2 100644 --- a/include/linux/mv643xx.h +++ b/include/linux/mv643xx.h @@ -1214,6 +1214,7 @@ struct mv64xxx_i2c_pdata { #define MV643XX_ETH_FORCE_BP_MODE_NO_JAM 0 #define MV643XX_ETH_FORCE_BP_MODE_JAM_TX (1<<7) #define MV643XX_ETH_FORCE_BP_MODE_JAM_TX_ON_RX_ERR (1<<8) +#define MV643XX_ETH_SERIAL_PORT_CONTROL_RESERVED (1<<9) #define MV643XX_ETH_FORCE_LINK_FAIL 0 #define MV643XX_ETH_DO_NOT_FORCE_LINK_FAIL (1<<10) #define MV643XX_ETH_RETRANSMIT_16_ATTEMPTS 0 @@ -1243,6 +1244,8 @@ struct mv64xxx_i2c_pdata { #define MV643XX_ETH_SET_MII_SPEED_TO_10 0 #define MV643XX_ETH_SET_MII_SPEED_TO_100 (1<<24) +#define MV643XX_ETH_MAX_RX_PACKET_MASK (0x7<<17) + #define MV643XX_ETH_PORT_SERIAL_CONTROL_DEFAULT_VALUE \ MV643XX_ETH_DO_NOT_FORCE_LINK_PASS | \ MV643XX_ETH_ENABLE_AUTO_NEG_FOR_DUPLX | \ -- cgit v1.2.2 From 01999873a455fe9104e91820c72849e608239928 Mon Sep 17 00:00:00 2001 From: Dale Farnsworth Date: Fri, 27 Jan 2006 01:18:01 -0700 Subject: [PATCH] mv643xx_eth: Clean up platform_data configuration We shouldn't expose the hardware register contents in platform_data. The only things we allow the user to configure are autoneg, speed, and duplex. Add specific platform_data fields for these values and remove the registers configs. Signed-off-by: Dale Farnsworth Signed-off-by: Jeff Garzik --- include/linux/mv643xx.h | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) (limited to 'include') diff --git a/include/linux/mv643xx.h b/include/linux/mv643xx.h index 7ffbeac7d2..955d3069d7 100644 --- a/include/linux/mv643xx.h +++ b/include/linux/mv643xx.h @@ -1288,23 +1288,15 @@ struct mv64xxx_i2c_pdata { #define MV643XX_ETH_NAME "mv643xx_eth" struct mv643xx_eth_platform_data { - /* - * Non-values for mac_addr, phy_addr, port_config, etc. - * override the default value. Setting the corresponding - * force_* field, causes the default value to be overridden - * even when zero. - */ - unsigned int force_phy_addr:1; - unsigned int force_port_config:1; - unsigned int force_port_config_extend:1; - unsigned int force_port_sdma_config:1; - unsigned int force_port_serial_control:1; - int phy_addr; char *mac_addr; /* pointer to mac address */ - u32 port_config; - u32 port_config_extend; - u32 port_sdma_config; - u32 port_serial_control; + u16 force_phy_addr; /* force override if phy_addr == 0 */ + u16 phy_addr; + + /* If speed is 0, then speed and duplex are autonegotiated. */ + int speed; /* 0, SPEED_10, SPEED_100, SPEED_1000 */ + int duplex; /* DUPLEX_HALF or DUPLEX_FULL */ + + /* non-zero values of the following fields override defaults */ u32 tx_queue_size; u32 rx_queue_size; u32 tx_sram_addr; -- cgit v1.2.2 From 24056bec086aaa99923b21c0e1a0e993bb1c7e2a Mon Sep 17 00:00:00 2001 From: Zhu Yi Date: Thu, 19 Jan 2006 16:21:09 +0800 Subject: [PATCH] ieee80211: Add LEAP authentication type Signed-off-by: Hong Liu Signed-off-by: Zhu Yi Signed-off-by: John W. Linville --- include/net/ieee80211.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/net/ieee80211.h b/include/net/ieee80211.h index 9a92aef8b0..3424a3ed66 100644 --- a/include/net/ieee80211.h +++ b/include/net/ieee80211.h @@ -220,6 +220,7 @@ struct ieee80211_snap_hdr { /* Authentication algorithms */ #define WLAN_AUTH_OPEN 0 #define WLAN_AUTH_SHARED_KEY 1 +#define WLAN_AUTH_LEAP 2 #define WLAN_AUTH_CHALLENGE_LEN 128 -- cgit v1.2.2 From 9184d9348a7a0e60d70d5f4c23de79fdbc72b9a3 Mon Sep 17 00:00:00 2001 From: Zhu Yi Date: Thu, 19 Jan 2006 16:22:32 +0800 Subject: [PATCH] ieee80211: Add TKIP crypt->build_iv This patch adds ieee80211 TKIP build_iv() method to support hardwares that can do TKIP encryption but relies on ieee80211 layer to build the IV. It also changes the build_iv() interface to return the key if possible after the IV is built (this is required by TKIP). Signed-off-by: Zhu Yi Signed-off-by: John W. Linville --- include/net/ieee80211_crypt.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/net/ieee80211_crypt.h b/include/net/ieee80211_crypt.h index cd82c3e998..eb476414fd 100644 --- a/include/net/ieee80211_crypt.h +++ b/include/net/ieee80211_crypt.h @@ -47,7 +47,8 @@ struct ieee80211_crypto_ops { /* deinitialize crypto context and free allocated private data */ void (*deinit) (void *priv); - int (*build_iv) (struct sk_buff * skb, int hdr_len, void *priv); + int (*build_iv) (struct sk_buff * skb, int hdr_len, + u8 *key, int keylen, void *priv); /* encrypt/decrypt return < 0 on error or >= 0 on success. The return * value from decrypt_mpdu is passed as the keyidx value for -- cgit v1.2.2 From b79e20b60997e427b701055a2c69fb0c1d507aa9 Mon Sep 17 00:00:00 2001 From: Zhu Yi Date: Thu, 19 Jan 2006 16:21:27 +0800 Subject: [PATCH] ieee80211: Add 802.11h data type and structures Add 802.11h data types and structure definitions to ieee80211.h. Signed-off-by: Hong Liu Signed-off-by: Zhu Yi Signed-off-by: John W. Linville --- include/net/ieee80211.h | 168 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 165 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/net/ieee80211.h b/include/net/ieee80211.h index 3424a3ed66..ff6ef9e1a6 100644 --- a/include/net/ieee80211.h +++ b/include/net/ieee80211.h @@ -300,6 +300,23 @@ enum ieee80211_reasoncode { WLAN_REASON_CIPHER_SUITE_REJECTED = 24, }; +/* Action categories - 802.11h */ +enum ieee80211_actioncategories { + WLAN_ACTION_SPECTRUM_MGMT = 0, + /* Reserved 1-127 */ + /* Error 128-255 */ +}; + +/* Action details - 802.11h */ +enum ieee80211_actiondetails { + WLAN_ACTION_CATEGORY_MEASURE_REQUEST = 0, + WLAN_ACTION_CATEGORY_MEASURE_REPORT = 1, + WLAN_ACTION_CATEGORY_TPC_REQUEST = 2, + WLAN_ACTION_CATEGORY_TPC_REPORT = 3, + WLAN_ACTION_CATEGORY_CHANNEL_SWITCH = 4, + /* 5 - 255 Reserved */ +}; + #define IEEE80211_STATMASK_SIGNAL (1<<0) #define IEEE80211_STATMASK_RSSI (1<<1) #define IEEE80211_STATMASK_NOISE (1<<2) @@ -378,6 +395,8 @@ struct ieee80211_rx_stats { u8 mask; u8 freq; u16 len; + u64 tsf; + u32 beacon_time; }; /* IEEE 802.11 requires that STA supports concurrent reception of at least @@ -609,6 +628,28 @@ struct ieee80211_auth { struct ieee80211_info_element info_element[0]; } __attribute__ ((packed)); +struct ieee80211_channel_switch { + u8 id; + u8 len; + u8 mode; + u8 channel; + u8 count; +} __attribute__ ((packed)); + +struct ieee80211_action { + struct ieee80211_hdr_3addr header; + u8 category; + u8 action; + union { + struct ieee80211_action_exchange { + u8 token; + struct ieee80211_info_element info_element[0]; + } exchange; + struct ieee80211_channel_switch channel_switch; + + } format; +} __attribute__ ((packed)); + struct ieee80211_disassoc { struct ieee80211_hdr_3addr header; __le16 reason; @@ -693,7 +734,15 @@ struct ieee80211_txb { /* QoS structure */ #define NETWORK_HAS_QOS_PARAMETERS (1<<3) #define NETWORK_HAS_QOS_INFORMATION (1<<4) -#define NETWORK_HAS_QOS_MASK (NETWORK_HAS_QOS_PARAMETERS | NETWORK_HAS_QOS_INFORMATION) +#define NETWORK_HAS_QOS_MASK (NETWORK_HAS_QOS_PARAMETERS | \ + NETWORK_HAS_QOS_INFORMATION) + +/* 802.11h */ +#define NETWORK_HAS_POWER_CONSTRAINT (1<<5) +#define NETWORK_HAS_CSA (1<<6) +#define NETWORK_HAS_QUIET (1<<7) +#define NETWORK_HAS_IBSS_DFS (1<<8) +#define NETWORK_HAS_TPC_REPORT (1<<9) #define QOS_QUEUE_NUM 4 #define QOS_OUI_LEN 3 @@ -749,6 +798,91 @@ struct ieee80211_tim_parameters { /*******************************************************/ +enum { /* ieee80211_basic_report.map */ + IEEE80211_BASIC_MAP_BSS = (1 << 0), + IEEE80211_BASIC_MAP_OFDM = (1 << 1), + IEEE80211_BASIC_MAP_UNIDENTIFIED = (1 << 2), + IEEE80211_BASIC_MAP_RADAR = (1 << 3), + IEEE80211_BASIC_MAP_UNMEASURED = (1 << 4), + /* Bits 5-7 are reserved */ + +}; +struct ieee80211_basic_report { + u8 channel; + __le64 start_time; + __le16 duration; + u8 map; +} __attribute__ ((packed)); + +enum { /* ieee80211_measurement_request.mode */ + /* Bit 0 is reserved */ + IEEE80211_MEASUREMENT_ENABLE = (1 << 1), + IEEE80211_MEASUREMENT_REQUEST = (1 << 2), + IEEE80211_MEASUREMENT_REPORT = (1 << 3), + /* Bits 4-7 are reserved */ +}; + +enum { + IEEE80211_REPORT_BASIC = 0, /* required */ + IEEE80211_REPORT_CCA = 1, /* optional */ + IEEE80211_REPORT_RPI = 2, /* optional */ + /* 3-255 reserved */ +}; + +struct ieee80211_measurement_params { + u8 channel; + __le64 start_time; + __le16 duration; +} __attribute__ ((packed)); + +struct ieee80211_measurement_request { + struct ieee80211_info_element ie; + u8 token; + u8 mode; + u8 type; + struct ieee80211_measurement_params params[0]; +} __attribute__ ((packed)); + +struct ieee80211_measurement_report { + struct ieee80211_info_element ie; + u8 token; + u8 mode; + u8 type; + union { + struct ieee80211_basic_report basic[0]; + } u; +} __attribute__ ((packed)); + +struct ieee80211_tpc_report { + u8 transmit_power; + u8 link_margin; +} __attribute__ ((packed)); + +struct ieee80211_channel_map { + u8 channel; + u8 map; +} __attribute__ ((packed)); + +struct ieee80211_ibss_dfs { + struct ieee80211_info_element ie; + u8 owner[ETH_ALEN]; + u8 recovery_interval; + struct ieee80211_channel_map channel_map[0]; +}; + +struct ieee80211_csa { + u8 mode; + u8 channel; + u8 count; +} __attribute__ ((packed)); + +struct ieee80211_quiet { + u8 count; + u8 period; + u8 duration; + u8 offset; +} __attribute__ ((packed)); + struct ieee80211_network { /* These entries are used to identify a unique network */ u8 bssid[ETH_ALEN]; @@ -768,7 +902,7 @@ struct ieee80211_network { u8 rates_ex_len; unsigned long last_scanned; u8 mode; - u8 flags; + u32 flags; u32 last_associate; u32 time_stamp[2]; u16 beacon_interval; @@ -780,6 +914,25 @@ struct ieee80211_network { u8 rsn_ie[MAX_WPA_IE_LEN]; size_t rsn_ie_len; struct ieee80211_tim_parameters tim; + + /* 802.11h info */ + + /* Power Constraint - mandatory if spctrm mgmt required */ + u8 power_constraint; + + /* TPC Report - mandatory if spctrm mgmt required */ + struct ieee80211_tpc_report tpc_report; + + /* IBSS DFS - mandatory if spctrm mgmt required and IBSS + * NOTE: This is variable length and so must be allocated dynamically */ + struct ieee80211_ibss_dfs *ibss_dfs; + + /* Channel Switch Announcement - optional if spctrm mgmt required */ + struct ieee80211_csa csa; + + /* Quiet - optional if spctrm mgmt required */ + struct ieee80211_quiet quiet; + struct list_head list; }; @@ -925,7 +1078,10 @@ struct ieee80211_device { int (*handle_auth) (struct net_device * dev, struct ieee80211_auth * auth); int (*handle_deauth) (struct net_device * dev, - struct ieee80211_auth * auth); + struct ieee80211_deauth * auth); + int (*handle_action) (struct net_device * dev, + struct ieee80211_action * action, + struct ieee80211_rx_stats * stats); int (*handle_disassoc) (struct net_device * dev, struct ieee80211_disassoc * assoc); int (*handle_beacon) (struct net_device * dev, @@ -1094,6 +1250,7 @@ extern int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, extern void ieee80211_rx_mgt(struct ieee80211_device *ieee, struct ieee80211_hdr_4addr *header, struct ieee80211_rx_stats *stats); +extern void ieee80211_network_reset(struct ieee80211_network *network); /* ieee80211_geo.c */ extern const struct ieee80211_geo *ieee80211_get_geo(struct ieee80211_device @@ -1106,6 +1263,11 @@ extern int ieee80211_is_valid_channel(struct ieee80211_device *ieee, extern int ieee80211_channel_to_index(struct ieee80211_device *ieee, u8 channel); extern u8 ieee80211_freq_to_channel(struct ieee80211_device *ieee, u32 freq); +extern u8 ieee80211_get_channel_flags(struct ieee80211_device *ieee, + u8 channel); +extern const struct ieee80211_channel *ieee80211_get_channel(struct + ieee80211_device + *ieee, u8 channel); /* ieee80211_wx.c */ extern int ieee80211_wx_get_scan(struct ieee80211_device *ieee, -- cgit v1.2.2 From a62c0fc526c344d8163f7a9e45e68cc63826ffd3 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 24 Jan 2006 17:05:22 +0900 Subject: [PATCH] libata: implement ata_drive_probe_reset() Most low level drivers share supported reset/classify actions and sequence. This patch implements ata_drive_probe_reset() which helps constructing ->probe_reset from three component operations - softreset, hardreset and postreset. This minimizes duplicate code and yet allows flexibility if needed. The three component operations can also be shared by EH later. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- include/linux/libata.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include') diff --git a/include/linux/libata.h b/include/linux/libata.h index a84d1c3a54..38e08ce2d1 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -241,6 +241,8 @@ struct ata_queued_cmd; /* typedefs */ typedef void (*ata_qc_cb_t) (struct ata_queued_cmd *qc); +typedef int (*ata_reset_fn_t)(struct ata_port *, int, unsigned int *); +typedef void (*ata_postreset_fn_t)(struct ata_port *ap, unsigned int *); struct ata_ioports { unsigned long cmd_addr; @@ -478,6 +480,9 @@ extern void ata_port_probe(struct ata_port *); extern void __sata_phy_reset(struct ata_port *ap); extern void sata_phy_reset(struct ata_port *ap); extern void ata_bus_reset(struct ata_port *ap); +extern int ata_drive_probe_reset(struct ata_port *ap, + ata_reset_fn_t softreset, ata_reset_fn_t hardreset, + ata_postreset_fn_t postreset, unsigned int *classes); extern void ata_port_disable(struct ata_port *); extern void ata_std_ports(struct ata_ioports *ioaddr); #ifdef CONFIG_PCI -- cgit v1.2.2 From c2bd58047b9b5c91a3b0a851de66a877f2eb7ae3 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 24 Jan 2006 17:05:22 +0900 Subject: [PATCH] libata: implement standard reset component operations and ->probe_reset Implement SRST, COMRESET and standard postreset component operations for ata_drive_probe_reset(), and use these three functions to implement ata_std_probe_reset. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- include/linux/libata.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'include') diff --git a/include/linux/libata.h b/include/linux/libata.h index 38e08ce2d1..474cdfa35d 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -483,6 +483,11 @@ extern void ata_bus_reset(struct ata_port *ap); extern int ata_drive_probe_reset(struct ata_port *ap, ata_reset_fn_t softreset, ata_reset_fn_t hardreset, ata_postreset_fn_t postreset, unsigned int *classes); +extern int ata_std_softreset(struct ata_port *ap, int verbose, + unsigned int *classes); +extern int sata_std_hardreset(struct ata_port *ap, int verbose, + unsigned int *class); +extern void ata_std_postreset(struct ata_port *ap, unsigned int *classes); extern void ata_port_disable(struct ata_port *); extern void ata_std_ports(struct ata_ioports *ioaddr); #ifdef CONFIG_PCI @@ -523,6 +528,7 @@ extern void ata_std_dev_select (struct ata_port *ap, unsigned int device); extern u8 ata_check_status(struct ata_port *ap); extern u8 ata_altstatus(struct ata_port *ap); extern void ata_exec_command(struct ata_port *ap, const struct ata_taskfile *tf); +extern int ata_std_probe_reset(struct ata_port *ap, unsigned int *classes); extern int ata_port_start (struct ata_port *ap); extern void ata_port_stop (struct ata_port *ap); extern void ata_host_stop (struct ata_host_set *host_set); -- cgit v1.2.2 From dd5eeb461ea572f82d34e1f2c4b88037df5afedb Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Mon, 30 Jan 2006 13:12:50 +0100 Subject: [PATCH] ieee80211: common wx auth code This patch creates two functions ieee80211_wx_set_auth and ieee80211_wx_get_auth that can be used by drivers for the wireless extension handlers instead of writing their own, if the implementation should be software only. These patches enable using bcm43xx devices with WPA and this seems (as far as I can tell) to be the only difference between the stock ieee80211 and softmac's ieee80211 left. Signed-Off-By: Johannes Berg Signed-off-by: John W. Linville --- include/net/ieee80211.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'include') diff --git a/include/net/ieee80211.h b/include/net/ieee80211.h index ff6ef9e1a6..4725ff861c 100644 --- a/include/net/ieee80211.h +++ b/include/net/ieee80211.h @@ -1285,6 +1285,14 @@ extern int ieee80211_wx_set_encodeext(struct ieee80211_device *ieee, extern int ieee80211_wx_get_encodeext(struct ieee80211_device *ieee, struct iw_request_info *info, union iwreq_data *wrqu, char *extra); +extern int ieee80211_wx_set_auth(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra); +extern int ieee80211_wx_get_auth(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra); static inline void ieee80211_increment_scans(struct ieee80211_device *ieee) { -- cgit v1.2.2 From bbab6fd81f26b210f0815d79064a3387c3a1ade3 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Mon, 6 Feb 2006 09:15:11 -0200 Subject: V4L/DVB (3265): Add count to tunertype struct The tuner_params element is an array of undefined length, with each array member being a set of parameters for each video standard type. The number of members in the tuner_params array will be stored in tuners[]->count Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- include/media/tuner-types.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/media/tuner-types.h b/include/media/tuner-types.h index 53ac66e011..ad9c171bfa 100644 --- a/include/media/tuner-types.h +++ b/include/media/tuner-types.h @@ -46,6 +46,7 @@ struct tuner_params { struct tunertype { char *name; + unsigned int count; struct tuner_params *params; }; -- cgit v1.2.2 From d97a11e091a0bf40f1cfb0bbf443ddd7b455b133 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 7 Feb 2006 06:48:40 -0200 Subject: V4L/DVB (3300): Add standard for South Korean NTSC-M using A2 audio. South Korea uses NTSC-M but with A2 audio instead of BTSC. Several audio chips need this information in order to set the correct audio processing registers. Acked-by: Mauro Carvalho Chehab Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/linux/videodev2.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index 6e33ce96ca..965c8902fe 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h @@ -638,6 +638,7 @@ typedef __u64 v4l2_std_id; #define V4L2_STD_NTSC_M ((v4l2_std_id)0x00001000) #define V4L2_STD_NTSC_M_JP ((v4l2_std_id)0x00002000) #define V4L2_STD_NTSC_443 ((v4l2_std_id)0x00004000) +#define V4L2_STD_NTSC_M_KR ((v4l2_std_id)0x00008000) #define V4L2_STD_SECAM_B ((v4l2_std_id)0x00010000) #define V4L2_STD_SECAM_D ((v4l2_std_id)0x00020000) @@ -670,7 +671,8 @@ typedef __u64 v4l2_std_id; V4L2_STD_PAL_H |\ V4L2_STD_PAL_I) #define V4L2_STD_NTSC (V4L2_STD_NTSC_M |\ - V4L2_STD_NTSC_M_JP) + V4L2_STD_NTSC_M_JP |\ + V4L2_STD_NTSC_M_KR) #define V4L2_STD_SECAM_DK (V4L2_STD_SECAM_D |\ V4L2_STD_SECAM_K |\ V4L2_STD_SECAM_K1) -- cgit v1.2.2 From 3593cab5d62c4c7abced1076710f9bc2d8847433 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Tue, 7 Feb 2006 06:49:14 -0200 Subject: V4L/DVB (3318b): sem2mutex: drivers/media/, #2 Semaphore to mutex conversion. The conversion was generated via scripts, and the result was validated automatically via a script as well. Signed-off-by: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Mauro Carvalho Chehab --- include/linux/videodev2.h | 3 ++- include/media/saa7146.h | 21 ++++++++++++--------- include/media/video-buf-dvb.h | 2 +- include/media/video-buf.h | 2 +- 4 files changed, 16 insertions(+), 12 deletions(-) (limited to 'include') diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index 965c8902fe..1dd8efeff3 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h @@ -17,6 +17,7 @@ #include /* need struct timeval */ #include #include +#include #endif #include /* need __user */ @@ -90,7 +91,7 @@ struct video_device /* for videodev.c intenal usage -- please don't touch */ int users; /* video_exclusive_{open|close} ... */ - struct semaphore lock; /* ... helper function uses these */ + struct mutex lock; /* ... helper function uses these */ char devfs_name[64]; /* devfs */ struct class_device class_dev; /* sysfs */ }; diff --git a/include/media/saa7146.h b/include/media/saa7146.h index 2bc634fcb7..fee579f10b 100644 --- a/include/media/saa7146.h +++ b/include/media/saa7146.h @@ -11,6 +11,8 @@ #include /* for i2c subsystem */ #include /* for accessing devices */ #include +#include + #include /* for vmalloc() */ #include /* for vmalloc_to_page() */ @@ -112,7 +114,7 @@ struct saa7146_dev /* different device locks */ spinlock_t slock; - struct semaphore lock; + struct mutex lock; unsigned char __iomem *mem; /* pointer to mapped IO memory */ int revision; /* chip revision; needed for bug-workarounds*/ @@ -133,15 +135,16 @@ struct saa7146_dev void (*vv_callback)(struct saa7146_dev *dev, unsigned long status); /* i2c-stuff */ - struct semaphore i2c_lock; - u32 i2c_bitrate; - struct saa7146_dma d_i2c; /* pointer to i2c memory */ - wait_queue_head_t i2c_wq; - int i2c_op; + struct mutex i2c_lock; + + u32 i2c_bitrate; + struct saa7146_dma d_i2c; /* pointer to i2c memory */ + wait_queue_head_t i2c_wq; + int i2c_op; /* memories */ - struct saa7146_dma d_rps0; - struct saa7146_dma d_rps1; + struct saa7146_dma d_rps0; + struct saa7146_dma d_rps1; }; /* from saa7146_i2c.c */ @@ -150,7 +153,7 @@ int saa7146_i2c_transfer(struct saa7146_dev *saa, const struct i2c_msg *msgs, in /* from saa7146_core.c */ extern struct list_head saa7146_devices; -extern struct semaphore saa7146_devices_lock; +extern struct mutex saa7146_devices_lock; int saa7146_register_extension(struct saa7146_extension*); int saa7146_unregister_extension(struct saa7146_extension*); struct saa7146_format* format_by_fourcc(struct saa7146_dev *dev, int fourcc); diff --git a/include/media/video-buf-dvb.h b/include/media/video-buf-dvb.h index ad0a07a3a8..b78d90fe62 100644 --- a/include/media/video-buf-dvb.h +++ b/include/media/video-buf-dvb.h @@ -11,7 +11,7 @@ struct videobuf_dvb { struct videobuf_queue dvbq; /* video-buf-dvb state info */ - struct semaphore lock; + struct mutex lock; struct task_struct *thread; int nfeeds; diff --git a/include/media/video-buf.h b/include/media/video-buf.h index 8ecfd78e00..d90dec5484 100644 --- a/include/media/video-buf.h +++ b/include/media/video-buf.h @@ -177,7 +177,7 @@ struct videobuf_queue_ops { }; struct videobuf_queue { - struct semaphore lock; + struct mutex lock; spinlock_t *irqlock; struct pci_dev *pci; -- cgit v1.2.2 From dde44589bf9fac0168c6ce6d097c99c33b18074f Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 2 Feb 2006 00:56:10 +0900 Subject: [PATCH] libata: implement ATA_FLAG_IN_EH port flag ATA_FLAG_IN_EH flag is set on entry to EH and cleared on completion. This patch just sets and clears the flag. Following patches will build normal qc execution / EH synchronization aroung this flag. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- include/linux/libata.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/linux/libata.h b/include/linux/libata.h index 474cdfa35d..55176df403 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -162,6 +162,8 @@ enum { ATA_FLAG_PIO_LBA48 = (1 << 13), /* Host DMA engine is LBA28 only */ ATA_FLAG_IRQ_MASK = (1 << 14), /* Mask IRQ in PIO xfers */ + ATA_FLAG_IN_EH = (1 << 15), /* EH in progress */ + ATA_QCFLAG_ACTIVE = (1 << 1), /* cmd not yet ack'd to scsi lyer */ ATA_QCFLAG_SG = (1 << 3), /* have s/g table? */ ATA_QCFLAG_SINGLE = (1 << 4), /* no s/g, just a single buffer */ -- cgit v1.2.2 From c18d06f89fd09ee0059c4899e615c471d59af66a Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 2 Feb 2006 00:56:10 +0900 Subject: [PATCH] libata: EH / pio tasks synchronization This patch makes sure that pio tasks are flushed before proceeding with EH. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- include/linux/libata.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/libata.h b/include/linux/libata.h index 55176df403..f4cd1eb734 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -162,7 +162,8 @@ enum { ATA_FLAG_PIO_LBA48 = (1 << 13), /* Host DMA engine is LBA28 only */ ATA_FLAG_IRQ_MASK = (1 << 14), /* Mask IRQ in PIO xfers */ - ATA_FLAG_IN_EH = (1 << 15), /* EH in progress */ + ATA_FLAG_FLUSH_PIO_TASK = (1 << 15), /* Flush PIO task */ + ATA_FLAG_IN_EH = (1 << 16), /* EH in progress */ ATA_QCFLAG_ACTIVE = (1 << 1), /* cmd not yet ack'd to scsi lyer */ ATA_QCFLAG_SG = (1 << 3), /* have s/g table? */ -- cgit v1.2.2 From 7944ea9522ce0ea32d57894b3dc2540b0bdca66e Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 2 Feb 2006 18:20:00 +0900 Subject: [PATCH] libata: add probeinit component operation to ata_drive_probe_reset() This patch adds probeinit component operation to ata_drive_probe_reset(). If present, this new operation is called before performing any reset. The operations's roll is to prepare @ap for following probe-reset operations. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- include/linux/libata.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/linux/libata.h b/include/linux/libata.h index f4cd1eb734..e8f29cefc3 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -244,6 +244,7 @@ struct ata_queued_cmd; /* typedefs */ typedef void (*ata_qc_cb_t) (struct ata_queued_cmd *qc); +typedef void (*ata_probeinit_fn_t)(struct ata_port *); typedef int (*ata_reset_fn_t)(struct ata_port *, int, unsigned int *); typedef void (*ata_postreset_fn_t)(struct ata_port *ap, unsigned int *); @@ -484,6 +485,7 @@ extern void __sata_phy_reset(struct ata_port *ap); extern void sata_phy_reset(struct ata_port *ap); extern void ata_bus_reset(struct ata_port *ap); extern int ata_drive_probe_reset(struct ata_port *ap, + ata_probeinit_fn_t probeinit, ata_reset_fn_t softreset, ata_reset_fn_t hardreset, ata_postreset_fn_t postreset, unsigned int *classes); extern int ata_std_softreset(struct ata_port *ap, int verbose, -- cgit v1.2.2 From 8a19ac89edbe9b702c10fd2039b8cb2db4644a5f Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 2 Feb 2006 18:20:00 +0900 Subject: [PATCH] libata: implement ata_std_probeinit() This patch implements the off-the-shelf probeinit component operation. Currently, all it does is waking up the PHY if it's a SATA port. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- include/linux/libata.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/libata.h b/include/linux/libata.h index e8f29cefc3..68b3fe6f9a 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -488,6 +488,7 @@ extern int ata_drive_probe_reset(struct ata_port *ap, ata_probeinit_fn_t probeinit, ata_reset_fn_t softreset, ata_reset_fn_t hardreset, ata_postreset_fn_t postreset, unsigned int *classes); +extern void ata_std_probeinit(struct ata_port *ap); extern int ata_std_softreset(struct ata_port *ap, int verbose, unsigned int *classes); extern int sata_std_hardreset(struct ata_port *ap, int verbose, -- cgit v1.2.2 From 341963b909a01d2f38d86f5db8dd1f8c80bd6dbf Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Fri, 10 Feb 2006 15:10:48 +0900 Subject: [PATCH] libata: add ATA_QCFLAG_EH_SCHEDULED Add ATA_QCFLAG_EH_SCHEDULED. If this flag is set, the qc is owned by EH and normal completion path is not allowed to finish it. This patch doesn't actually use this flag. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- include/linux/libata.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/libata.h b/include/linux/libata.h index 68b3fe6f9a..5c70a57f93 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -169,6 +169,7 @@ enum { ATA_QCFLAG_SG = (1 << 3), /* have s/g table? */ ATA_QCFLAG_SINGLE = (1 << 4), /* no s/g, just a single buffer */ ATA_QCFLAG_DMAMAP = ATA_QCFLAG_SG | ATA_QCFLAG_SINGLE, + ATA_QCFLAG_EH_SCHEDULED = (1 << 5), /* EH scheduled */ /* various lengths of time */ ATA_TMOUT_EDD = 5 * HZ, /* heuristic */ -- cgit v1.2.2 From f29841e08fa20a7f2c8bc1b70306975299c66ee7 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Fri, 10 Feb 2006 15:10:48 +0900 Subject: [PATCH] libata: implement ata_scsi_timed_out() Implement ata_scsi_timed_out(), to be used as scsi_host_template->eh_timed_out callback for all libata drivers. Without this function, the following race exists. If a qc completes after SCSI timer expires but before libata EH kicks in, the qc gets completed but the scsicmd still gets passed to libata EH resulting in ->eng_timeout invocation with NULL qc, which none is handling properly. This patch makes sure that scmd and qc share the same lifetime. Original idea from Jeff Garzik . Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- include/linux/libata.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/libata.h b/include/linux/libata.h index 5c70a57f93..c1e198655b 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -509,6 +509,7 @@ extern void ata_host_set_remove(struct ata_host_set *host_set); extern int ata_scsi_detect(struct scsi_host_template *sht); extern int ata_scsi_ioctl(struct scsi_device *dev, int cmd, void __user *arg); extern int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)); +extern enum scsi_eh_timer_return ata_scsi_timed_out(struct scsi_cmnd *cmd); extern int ata_scsi_error(struct Scsi_Host *host); extern void ata_eh_qc_complete(struct ata_queued_cmd *qc); extern void ata_eh_qc_retry(struct ata_queued_cmd *qc); -- cgit v1.2.2 From 76014427e60f7ecfdc689dfbcb48e9760e1da4fb Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sat, 11 Feb 2006 15:13:49 +0900 Subject: [PATCH] libata: inline ata_qc_complete() This patch inlines ata_qc_complete() and uninlines __ata_qc_complete() as suggested by Jeff Garzik. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- include/linux/libata.h | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/libata.h b/include/linux/libata.h index c1e198655b..695d9ae6ec 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -556,7 +556,7 @@ extern void ata_bmdma_start (struct ata_queued_cmd *qc); extern void ata_bmdma_stop(struct ata_queued_cmd *qc); extern u8 ata_bmdma_status(struct ata_port *ap); extern void ata_bmdma_irq_clear(struct ata_port *ap); -extern void ata_qc_complete(struct ata_queued_cmd *qc); +extern void __ata_qc_complete(struct ata_queued_cmd *qc); extern void ata_eng_timeout(struct ata_port *ap); extern void ata_scsi_simulate(struct ata_port *ap, struct ata_device *dev, struct scsi_cmnd *cmd, @@ -756,6 +756,24 @@ static inline void ata_qc_reinit(struct ata_queued_cmd *qc) ata_tf_init(qc->ap, &qc->tf, qc->dev->devno); } +/** + * ata_qc_complete - Complete an active ATA command + * @qc: Command to complete + * @err_mask: ATA Status register contents + * + * Indicate to the mid and upper layers that an ATA + * command has completed, with either an ok or not-ok status. + * + * LOCKING: + * spin_lock_irqsave(host_set lock) + */ +static inline void ata_qc_complete(struct ata_queued_cmd *qc) +{ + if (unlikely(qc->flags & ATA_QCFLAG_EH_SCHEDULED)) + return; + + __ata_qc_complete(qc); +} /** * ata_irq_on - Enable interrupts on a port. -- cgit v1.2.2 From bef4a456b8dc8b3638f4d49a25a89e1467da9483 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sat, 11 Feb 2006 19:11:13 +0900 Subject: [PATCH] libata: kill assert() macro libata assert() now has no user left. Kill it. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- include/linux/libata.h | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'include') diff --git a/include/linux/libata.h b/include/linux/libata.h index 695d9ae6ec..83a1f2ead8 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -62,16 +62,6 @@ #define BPRINTK(fmt, args...) if (ap->flags & ATA_FLAG_DEBUGMSG) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ## args) -#ifdef ATA_NDEBUG -#define assert(expr) -#else -#define assert(expr) \ - if(unlikely(!(expr))) { \ - printk(KERN_ERR "Assertion failed! %s,%s,%s,line=%d\n", \ - #expr,__FILE__,__FUNCTION__,__LINE__); \ - } -#endif - /* NEW: debug levels */ #define HAVE_LIBATA_MSG 1 -- cgit v1.2.2 From 0e949ff304a7ca07db38c17fbbf3ead1085d7bbf Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 12 Feb 2006 22:47:04 +0900 Subject: [PATCH] libata: implement ata_dev_id_c_string() ata_dev_id_c_string() reads ATA string from the specified offset of the given IDENTIFY PAGE and puts it in the specified buffer in trimmed and NULL-terminated form. The caller must supply a buffer which is one byte larger than the maximum size of the target ID string. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- include/linux/libata.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/linux/libata.h b/include/linux/libata.h index 83a1f2ead8..0853032673 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -540,6 +540,8 @@ extern void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg, extern unsigned int ata_dev_classify(const struct ata_taskfile *tf); extern void ata_dev_id_string(const u16 *id, unsigned char *s, unsigned int ofs, unsigned int len); +extern void ata_dev_id_c_string(const u16 *id, unsigned char *s, + unsigned int ofs, unsigned int len); extern void ata_dev_config(struct ata_port *ap, unsigned int i); extern void ata_bmdma_setup (struct ata_queued_cmd *qc); extern void ata_bmdma_start (struct ata_queued_cmd *qc); -- cgit v1.2.2 From 3d2ca91095f8ab6dc0cb925374eec62fa5336764 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 12 Feb 2006 22:47:04 +0900 Subject: [PATCH] libata: separate out ata_id_major_version() Separate out ATA major version calculation from ata_dev_identify() into ata_id_major_version(). It's preparation for splitting ata_dev_identify(). Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- include/linux/ata.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'include') diff --git a/include/linux/ata.h b/include/linux/ata.h index a8155ca494..b02a16c435 100644 --- a/include/linux/ata.h +++ b/include/linux/ata.h @@ -267,6 +267,16 @@ struct ata_taskfile { ((u64) (id)[(n) + 1] << 16) | \ ((u64) (id)[(n) + 0]) ) +static inline unsigned int ata_id_major_version(const u16 *id) +{ + unsigned int mver; + + for (mver = 14; mver >= 1; mver--) + if (id[ATA_ID_MAJOR_VER] & (1 << mver)) + break; + return mver; +} + static inline int ata_id_current_chs_valid(const u16 *id) { /* For ATA-1 devices, if the INITIALIZE DEVICE PARAMETERS command -- cgit v1.2.2 From 6e7846e9c548443c86cfbad9e4defb4bdcfc538b Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 12 Feb 2006 23:32:58 +0900 Subject: [PATCH] libata: move cdb_len for host to device cdb_len is per-device property. Sharing cdb_len on ap results in inaccurate configuration on revalidation and hotplugging. This patch makes cdb_len per-device. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- include/linux/libata.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/libata.h b/include/linux/libata.h index 0853032673..853c98859a 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -348,6 +348,7 @@ struct ata_device { unsigned int multi_count; /* sectors count for READ/WRITE MULTIPLE */ + unsigned int cdb_len; /* for CHS addressing */ u16 cylinders; /* Number of cylinders */ @@ -377,7 +378,6 @@ struct ata_port { unsigned int mwdma_mask; unsigned int udma_mask; unsigned int cbl; /* cable type; ATA_CBL_xxx */ - unsigned int cdb_len; struct ata_device device[ATA_MAX_DEVICES]; -- cgit v1.2.2 From b00eec1d58ee71131375bfeb86e64bceec3f5618 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 12 Feb 2006 23:32:59 +0900 Subject: [PATCH] libata: add per-device max_sectors If a low level driver wants to control max_sectors, it had to adjust ap->host->max_sectors and set ATA_DFLAG_LOCK_SECTORS to tell ata_scsi_slave_config not to override the limit. This is not only cumbersome but also incorrect for hosts which support more than one devices per port. This patch adds per-device ->max_sectors. If the field is unset (zero), libata core layer will adjust ->max_sectors according to default rules. If the field is set, libata honors the setting. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- include/linux/libata.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/linux/libata.h b/include/linux/libata.h index 853c98859a..afe4645712 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -122,8 +122,7 @@ enum { /* struct ata_device stuff */ ATA_DFLAG_LBA48 = (1 << 0), /* device supports LBA48 */ ATA_DFLAG_PIO = (1 << 1), /* device currently in PIO mode */ - ATA_DFLAG_LOCK_SECTORS = (1 << 2), /* don't adjust max_sectors */ - ATA_DFLAG_LBA = (1 << 3), /* device supports LBA */ + ATA_DFLAG_LBA = (1 << 2), /* device supports LBA */ ATA_DEV_UNKNOWN = 0, /* unknown device */ ATA_DEV_ATA = 1, /* ATA device */ @@ -348,6 +347,7 @@ struct ata_device { unsigned int multi_count; /* sectors count for READ/WRITE MULTIPLE */ + unsigned int max_sectors; /* per-device max sectors */ unsigned int cdb_len; /* for CHS addressing */ -- cgit v1.2.2 From 6a62a04d4705df4f9f9bee39e889b9e920eeca47 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 13 Feb 2006 10:02:46 +0900 Subject: [PATCH] libata: rename ata_dev_id_[c_]string() This patch renames ata_dev_id_[c_]string() to ata_id_[c_]string(). All other functions which read data from ATA ID data start with ata_id and those two function names were getting too long. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- include/linux/libata.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/linux/libata.h b/include/linux/libata.h index afe4645712..0d6bf50ad0 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -538,10 +538,10 @@ extern void ata_sg_init_one(struct ata_queued_cmd *qc, void *buf, extern void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg, unsigned int n_elem); extern unsigned int ata_dev_classify(const struct ata_taskfile *tf); -extern void ata_dev_id_string(const u16 *id, unsigned char *s, - unsigned int ofs, unsigned int len); -extern void ata_dev_id_c_string(const u16 *id, unsigned char *s, - unsigned int ofs, unsigned int len); +extern void ata_id_string(const u16 *id, unsigned char *s, + unsigned int ofs, unsigned int len); +extern void ata_id_c_string(const u16 *id, unsigned char *s, + unsigned int ofs, unsigned int len); extern void ata_dev_config(struct ata_port *ap, unsigned int i); extern void ata_bmdma_setup (struct ata_queued_cmd *qc); extern void ata_bmdma_start (struct ata_queued_cmd *qc); -- cgit v1.2.2 From 0004fd59d57a5875db8897966c414a88b5dad481 Mon Sep 17 00:00:00 2001 From: Markus Rechberger Date: Mon, 27 Feb 2006 00:07:27 -0300 Subject: V4L/DVB (3291): Added support for xc3028 analogue tuner (Hauppauge HVR900, Terratec Hybrid XS) Added support for xc3028 to v4l which adds support for: * Terratec Hybrid XS (analogue) * Hauppauge HVR 900 (analogue) Signed-off-by: Markus Rechberger Signed-off-by: Mauro Carvalho Chehab --- include/media/tuner.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include') diff --git a/include/media/tuner.h b/include/media/tuner.h index a5beeac495..f51759c0d1 100644 --- a/include/media/tuner.h +++ b/include/media/tuner.h @@ -117,6 +117,8 @@ #define TUNER_TNF_5335MF 69 /* Sabrent Bt848 */ #define TUNER_SAMSUNG_TCPN_2121P30A 70 /* Hauppauge PVR-500MCE NTSC */ +#define TUNER_XCEIVE_XC3028 71 + /* tv card specific */ #define TDA9887_PRESENT (1<<0) #define TDA9887_PORT1_INACTIVE (1<<1) @@ -209,6 +211,7 @@ struct tuner { extern unsigned const int tuner_count; extern int microtune_init(struct i2c_client *c); +extern int xc3028_init(struct i2c_client *c); extern int tda8290_init(struct i2c_client *c); extern int tda8290_probe(struct i2c_client *c); extern int tea5767_tuner_init(struct i2c_client *c); -- cgit v1.2.2 From 749eef857948a3de789b7d0e3b96d92199d723cf Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 27 Feb 2006 00:07:40 -0300 Subject: V4L/DVB (3334): Added ET61X251 fourcc type Signed-off-by: Mauro Carvalho Chehab --- include/linux/videodev2.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index 1dd8efeff3..3f15043534 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h @@ -326,6 +326,7 @@ struct v4l2_pix_format #define V4L2_PIX_FMT_SN9C10X v4l2_fourcc('S','9','1','0') /* SN9C10x compression */ #define V4L2_PIX_FMT_PWC1 v4l2_fourcc('P','W','C','1') /* pwc older webcam */ #define V4L2_PIX_FMT_PWC2 v4l2_fourcc('P','W','C','2') /* pwc newer webcam */ +#define V4L2_PIX_FMT_ET61X251 v4l2_fourcc('E','6','2','5') /* ET61X251 compression */ /* * F O R M A T E N U M E R A T I O N -- cgit v1.2.2 From 41f38b43e0bfbb2ba1ef3c778f376dad8820b214 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 27 Feb 2006 00:08:49 -0300 Subject: V4L/DVB (3371): Add debug to ioctl arguments. Added a new function that allows printing ioctl arguments. This makes easier to include debug code under v4l ioctl handling. Also fixed some declarations on internal ioctl. Signed-off-by: Mauro Carvalho Chehab --- include/media/v4l2-common.h | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h index 234e9cf7e8..c44741e78f 100644 --- a/include/media/v4l2-common.h +++ b/include/media/v4l2-common.h @@ -58,6 +58,9 @@ /* Prints the ioctl in a human-readable format */ extern void v4l_printk_ioctl(unsigned int cmd); +/* Prints the ioctl and arg in a human-readable format */ +extern void v4l_printk_ioctl_arg(char *s,unsigned int cmd, void *arg); + /* Use this macro for non-I2C drivers. Pass the driver name as the first arg. */ #define v4l_print_ioctl(name, cmd) \ do { \ @@ -185,11 +188,11 @@ struct msp_matrix { register contains invalid or erroneous data -EIO is returned. Note that you must fill in the 'id' member and the 'field' member (to determine whether CC data from the first or second field should be obtained). */ -#define VIDIOC_INT_G_VBI_DATA _IOWR('d', 106, struct v4l2_sliced_vbi_data *) +#define VIDIOC_INT_G_VBI_DATA _IOWR('d', 106, struct v4l2_sliced_vbi_data) /* Returns the chip identifier or V4L2_IDENT_UNKNOWN if no identification can be made. */ -#define VIDIOC_INT_G_CHIP_IDENT _IOR ('d', 107, enum v4l2_chip_ident *) +#define VIDIOC_INT_G_CHIP_IDENT _IOR ('d', 107, enum v4l2_chip_ident) /* Sets I2S speed in bps. This is used to provide a standard way to select I2S clock used by driving digital audio streams at some board designs. @@ -214,8 +217,8 @@ struct v4l2_routing { These four commands should only be sent directly to an i2c device, they should not be broadcast as the routing is very device specific. */ #define VIDIOC_INT_S_AUDIO_ROUTING _IOW ('d', 109, struct v4l2_routing) -#define VIDIOC_INT_G_AUDIO_ROUTING _IOR ('d', 110, struct v4l2_routing *) +#define VIDIOC_INT_G_AUDIO_ROUTING _IOR ('d', 110, struct v4l2_routing) #define VIDIOC_INT_S_VIDEO_ROUTING _IOW ('d', 111, struct v4l2_routing) -#define VIDIOC_INT_G_VIDEO_ROUTING _IOR ('d', 112, struct v4l2_routing *) +#define VIDIOC_INT_G_VIDEO_ROUTING _IOR ('d', 112, struct v4l2_routing) #endif /* V4L2_COMMON_H_ */ -- cgit v1.2.2 From f05cce863fa399dd79c5aa3896d608b8b86d8030 Mon Sep 17 00:00:00 2001 From: Andreas Oberritter Date: Mon, 27 Feb 2006 00:09:00 -0300 Subject: V4L/DVB (3375): Add AUDIO_GET_PTS and VIDEO_GET_PTS ioctls Add two new ioctls to read the 33 bit presentation time stamp from audio and video devices as defined in ITU T-REC-H.222.0 and ISO/IEC 13818-1. Acked-by: Johannes Stezenbach Signed-off-by: Andreas Oberritter Signed-off-by: Mauro Carvalho Chehab --- include/linux/dvb/audio.h | 13 +++++++++++++ include/linux/dvb/video.h | 13 +++++++++++++ 2 files changed, 26 insertions(+) (limited to 'include') diff --git a/include/linux/dvb/audio.h b/include/linux/dvb/audio.h index 2b87970846..0874a67c6b 100644 --- a/include/linux/dvb/audio.h +++ b/include/linux/dvb/audio.h @@ -121,4 +121,17 @@ typedef uint16_t audio_attributes_t; #define AUDIO_SET_ATTRIBUTES _IOW('o', 17, audio_attributes_t) #define AUDIO_SET_KARAOKE _IOW('o', 18, audio_karaoke_t) +/** + * AUDIO_GET_PTS + * + * Read the 33 bit presentation time stamp as defined + * in ITU T-REC-H.222.0 / ISO/IEC 13818-1. + * + * The PTS should belong to the currently played + * frame if possible, but may also be a value close to it + * like the PTS of the last decoded frame or the last PTS + * extracted by the PES parser. + */ +#define AUDIO_GET_PTS _IOR('o', 19, __u64) + #endif /* _DVBAUDIO_H_ */ diff --git a/include/linux/dvb/video.h b/include/linux/dvb/video.h index b1999bfeaa..1f7fa0351d 100644 --- a/include/linux/dvb/video.h +++ b/include/linux/dvb/video.h @@ -200,4 +200,17 @@ typedef uint16_t video_attributes_t; #define VIDEO_GET_SIZE _IOR('o', 55, video_size_t) #define VIDEO_GET_FRAME_RATE _IOR('o', 56, unsigned int) +/** + * VIDEO_GET_PTS + * + * Read the 33 bit presentation time stamp as defined + * in ITU T-REC-H.222.0 / ISO/IEC 13818-1. + * + * The PTS should belong to the currently played + * frame if possible, but may also be a value close to it + * like the PTS of the last decoded frame or the last PTS + * extracted by the PES parser. + */ +#define VIDEO_GET_PTS _IOR('o', 57, __u64) + #endif /*_DVBVIDEO_H_*/ -- cgit v1.2.2 From 597afd21401c85bdf9441830abf431c2be6fd45f Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 1 Mar 2006 01:25:38 +0900 Subject: [PATCH] libata: seperate out ata_class_present() Seperate out ata_class_present() from ata_dev_present(). This is useful because new reset mechanism deals with classes[] directly. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- include/linux/libata.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/linux/libata.h b/include/linux/libata.h index 66b6847225..22e86cb2d1 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -645,10 +645,14 @@ static inline unsigned int ata_tag_valid(unsigned int tag) return (tag < ATA_MAX_QUEUE) ? 1 : 0; } +static inline unsigned int ata_class_present(unsigned int class) +{ + return class == ATA_DEV_ATA || class == ATA_DEV_ATAPI; +} + static inline unsigned int ata_dev_present(const struct ata_device *dev) { - return ((dev->class == ATA_DEV_ATA) || - (dev->class == ATA_DEV_ATAPI)); + return ata_class_present(dev->class); } static inline u8 ata_chk_status(struct ata_port *ap) -- cgit v1.2.2 From d9572b1d5e60b63e27e17f1f7771c5a26dd5d81e Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 1 Mar 2006 16:09:35 +0900 Subject: [PATCH] libata: convert dev->id to pointer Convert dev->id from array to pointer. This is to accomodate revalidation. During revalidation, both old and new IDENTIFY pages should be accessible and single ->id array doesn't cut it. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- include/linux/libata.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/libata.h b/include/linux/libata.h index 22e86cb2d1..9f273dd195 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -339,7 +339,7 @@ struct ata_device { unsigned long flags; /* ATA_DFLAG_xxx */ unsigned int class; /* ATA_DEV_xxx */ unsigned int devno; /* 0 or 1 */ - u16 id[ATA_ID_WORDS]; /* IDENTIFY xxx DEVICE data */ + u16 *id; /* IDENTIFY xxx DEVICE data */ u8 pio_mode; u8 dma_mode; u8 xfer_mode; -- cgit v1.2.2 From 4b2f3ededc035525038a7a9247074243dac6b351 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 1 Mar 2006 16:09:36 +0900 Subject: [PATCH] libata: fold ata_dev_config() into ata_dev_configure() ata_dev_config() needs to be done everytime a device is configured. Fold it into ata_dev_configure(). Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- include/linux/libata.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include') diff --git a/include/linux/libata.h b/include/linux/libata.h index 9f273dd195..86a504f0ef 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -542,7 +542,6 @@ extern void ata_id_string(const u16 *id, unsigned char *s, unsigned int ofs, unsigned int len); extern void ata_id_c_string(const u16 *id, unsigned char *s, unsigned int ofs, unsigned int len); -extern void ata_dev_config(struct ata_port *ap, unsigned int i); extern void ata_bmdma_setup (struct ata_queued_cmd *qc); extern void ata_bmdma_start (struct ata_queued_cmd *qc); extern void ata_bmdma_stop(struct ata_queued_cmd *qc); -- cgit v1.2.2 From 8f903c708fcc2b579ebf16542bf6109bad593a1d Mon Sep 17 00:00:00 2001 From: Jay Vosburgh Date: Tue, 21 Feb 2006 16:36:44 -0800 Subject: [PATCH] bonding: suppress duplicate packets Originally submitted by Kenzo Iwami; his original description is: The current bonding driver receives duplicate packets when broadcast/ multicast packets are sent by other devices or packets are flooded by the switch. In this patch, new flags are added in priv_flags of net_device structure to let the bonding driver discard duplicate packets in dev.c:skb_bond(). Modified by Jay Vosburgh to change a define name, update some comments, rearrange the new skb_bond() for clarity, clear all bonding priv_flags on slave release, and update the driver version. Signed-off-by: Kenzo Iwami Signed-off-by: Jay Vosburgh Signed-off-by: Jeff Garzik --- include/linux/if.h | 3 +++ include/linux/if_ether.h | 1 + 2 files changed, 4 insertions(+) (limited to 'include') diff --git a/include/linux/if.h b/include/linux/if.h index ce627d9092..12c6f6d157 100644 --- a/include/linux/if.h +++ b/include/linux/if.h @@ -52,6 +52,9 @@ /* Private (from user) interface flags (netdevice->priv_flags). */ #define IFF_802_1Q_VLAN 0x1 /* 802.1Q VLAN device. */ #define IFF_EBRIDGE 0x2 /* Ethernet bridging device. */ +#define IFF_SLAVE_INACTIVE 0x4 /* bonding slave not the curr. active */ +#define IFF_MASTER_8023AD 0x8 /* bonding master, 802.3ad. */ +#define IFF_MASTER_ALB 0x10 /* bonding master, balance-alb. */ #define IF_GET_IFACE 0x0001 /* for querying only */ #define IF_GET_PROTO 0x0002 diff --git a/include/linux/if_ether.h b/include/linux/if_ether.h index 7a92c1ce14..ab08f35cbc 100644 --- a/include/linux/if_ether.h +++ b/include/linux/if_ether.h @@ -61,6 +61,7 @@ #define ETH_P_8021Q 0x8100 /* 802.1Q VLAN Extended Header */ #define ETH_P_IPX 0x8137 /* IPX over DIX */ #define ETH_P_IPV6 0x86DD /* IPv6 over bluebook */ +#define ETH_P_SLOW 0x8809 /* Slow Protocol. See 802.3ad 43B */ #define ETH_P_WCCP 0x883E /* Web-cache coordination protocol * defined in draft-wilson-wrec-wccp-v2-00.txt */ #define ETH_P_PPP_DISC 0x8863 /* PPPoE discovery messages */ -- cgit v1.2.2 From 623a3128aa2b86caa8e06e762e9e444177e4fa47 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 5 Mar 2006 17:55:58 +0900 Subject: [PATCH] libata: implement ata_dev_revalidate() ata_dev_revalidate() re-reads IDENTIFY PAGE of the given device and makes sure it's the same device as the configured one. Once it's verified that it's the same device, @dev is configured according to newly read IDENTIFY PAGE. Note that revalidation currently doesn't invoke transfer mode reconfiguration. Criteria for 'same device' * same class (of course) * same model string * same serial string * if ATA, same n_sectors (to catch geometry parameter changes) Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- include/linux/libata.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/linux/libata.h b/include/linux/libata.h index 86a504f0ef..66dce58f19 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -485,6 +485,8 @@ extern int ata_std_softreset(struct ata_port *ap, int verbose, extern int sata_std_hardreset(struct ata_port *ap, int verbose, unsigned int *class); extern void ata_std_postreset(struct ata_port *ap, unsigned int *classes); +extern int ata_dev_revalidate(struct ata_port *ap, struct ata_device *dev, + int post_reset); extern void ata_port_disable(struct ata_port *); extern void ata_std_ports(struct ata_ioports *ioaddr); #ifdef CONFIG_PCI -- cgit v1.2.2 From 780dfef37e2c941985b708f67aa0074edc922bea Mon Sep 17 00:00:00 2001 From: Chris Pascoe Date: Tue, 28 Feb 2006 08:34:59 -0300 Subject: V4L/DVB (3408): DViCO FusionHDTV DVB-T Hybrid and ZL10353-based FusionHDTV DVB-T Plus support Add support for the FE6600 tuner used on the DVB-T Hybrid board. Add support for the Zarlink ZL10353 DVB-T demodulator, which supersedes the MT352, used on the DViCO FusionHDTV DVB-T Hybrid and later model Plus boards. Signed-off-by: Chris Pascoe Signed-off-by: Mauro Carvalho Chehab --- include/media/tuner.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/media/tuner.h b/include/media/tuner.h index f51759c0d1..039c77e02d 100644 --- a/include/media/tuner.h +++ b/include/media/tuner.h @@ -116,9 +116,10 @@ #define TUNER_PHILIPS_TUV1236D 68 /* ATI HDTV Wonder */ #define TUNER_TNF_5335MF 69 /* Sabrent Bt848 */ #define TUNER_SAMSUNG_TCPN_2121P30A 70 /* Hauppauge PVR-500MCE NTSC */ - #define TUNER_XCEIVE_XC3028 71 +#define TUNER_FE6600 72 /* DViCO FusionHDTV DVB-T Hybrid */ + /* tv card specific */ #define TDA9887_PRESENT (1<<0) #define TDA9887_PORT1_INACTIVE (1<<1) -- cgit v1.2.2 From 91ae3299d7d3493a25e5f26cbaceeb18e7760ef3 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Wed, 1 Mar 2006 00:04:42 -0300 Subject: V4L/DVB (3411): FE6600 is a Thomson tuner - The tuner used in DViCO FusionHDTV DVB-T hybrid is made by Thomson - renamed tuner and dvb_pll structs accordingly Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- include/media/tuner.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/media/tuner.h b/include/media/tuner.h index 039c77e02d..02d7d9a76f 100644 --- a/include/media/tuner.h +++ b/include/media/tuner.h @@ -118,7 +118,7 @@ #define TUNER_SAMSUNG_TCPN_2121P30A 70 /* Hauppauge PVR-500MCE NTSC */ #define TUNER_XCEIVE_XC3028 71 -#define TUNER_FE6600 72 /* DViCO FusionHDTV DVB-T Hybrid */ +#define TUNER_THOMSON_FE6600 72 /* DViCO FusionHDTV DVB-T Hybrid */ /* tv card specific */ #define TDA9887_PRESENT (1<<0) -- cgit v1.2.2 From 86e45b6bd6900c4a0b3666fb18b46e215f775c4f Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 5 Mar 2006 15:29:09 +0900 Subject: [PATCH] libata: implement port_task Implement port_task. LLDD's can schedule a function to be executed with context after specified delay. libata core takes care of synchronization against EH. This is generalized form of pio_task and packet_task which are tied to PIO hsm implementation. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- include/linux/libata.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include') diff --git a/include/linux/libata.h b/include/linux/libata.h index 66dce58f19..3ad2570f66 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -388,6 +388,8 @@ struct ata_port { struct ata_host_stats stats; struct ata_host_set *host_set; + struct work_struct port_task; + struct work_struct packet_task; struct work_struct pio_task; @@ -515,6 +517,8 @@ extern int ata_ratelimit(void); extern unsigned int ata_busy_sleep(struct ata_port *ap, unsigned long timeout_pat, unsigned long timeout); +extern void ata_port_queue_task(struct ata_port *ap, void (*fn)(void *), + void *data, unsigned long delay); /* * Default driver ops implementations -- cgit v1.2.2 From 507ceda00302c071029277652d9faa5a0a55419a Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 5 Mar 2006 15:29:09 +0900 Subject: [PATCH] libata: kill unused pio_task and packet_task Kill unused pio_task and packet_task. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- include/linux/libata.h | 3 --- 1 file changed, 3 deletions(-) (limited to 'include') diff --git a/include/linux/libata.h b/include/linux/libata.h index 3ad2570f66..9ad020ac85 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -390,9 +390,6 @@ struct ata_port { struct work_struct port_task; - struct work_struct packet_task; - - struct work_struct pio_task; unsigned int hsm_task_state; unsigned long pio_task_timeout; -- cgit v1.2.2 From 2e755f68ee23b03484fde18d978f910cc5479cb8 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 5 Mar 2006 15:29:09 +0900 Subject: [PATCH] libata: rename ATA_FLAG_FLUSH_PIO_TASK to ATA_FLAG_FLUSH_PORT_TASK Rename ATA_FLAG_FLUSH_PIO_TASK to ATA_FLAG_FLUSH_PORT_TASK. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- include/linux/libata.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/libata.h b/include/linux/libata.h index 9ad020ac85..15674923cc 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -151,7 +151,7 @@ enum { ATA_FLAG_PIO_LBA48 = (1 << 13), /* Host DMA engine is LBA28 only */ ATA_FLAG_IRQ_MASK = (1 << 14), /* Mask IRQ in PIO xfers */ - ATA_FLAG_FLUSH_PIO_TASK = (1 << 15), /* Flush PIO task */ + ATA_FLAG_FLUSH_PORT_TASK = (1 << 15), /* Flush port task */ ATA_FLAG_IN_EH = (1 << 16), /* EH in progress */ ATA_QCFLAG_ACTIVE = (1 << 1), /* cmd not yet ack'd to scsi lyer */ -- cgit v1.2.2 From 1da7b0d01b20bf21f3263d8d2f17fa49a214d773 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 6 Mar 2006 04:31:56 +0900 Subject: [PATCH] libata: improve xfer mask constants and update ata_mode_string() Add ATA_BITS_*, ATA_MASK_* macros and reorder xfer_mask fields such that higher transfer mode is placed at higher order bit. As thie reordering breaks ata_mode_string(), this patch also rewrites ata_mode_string(). Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- include/linux/libata.h | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/linux/libata.h b/include/linux/libata.h index 15674923cc..239408ecfd 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -188,11 +188,19 @@ enum { PORT_DISABLED = 2, /* encoding various smaller bitmaps into a single - * unsigned long bitmap + * unsigned int bitmap */ - ATA_SHIFT_UDMA = 0, - ATA_SHIFT_MWDMA = 8, - ATA_SHIFT_PIO = 11, + ATA_BITS_PIO = 5, + ATA_BITS_MWDMA = 3, + ATA_BITS_UDMA = 8, + + ATA_SHIFT_PIO = 0, + ATA_SHIFT_MWDMA = ATA_SHIFT_PIO + ATA_BITS_PIO, + ATA_SHIFT_UDMA = ATA_SHIFT_MWDMA + ATA_BITS_MWDMA, + + ATA_MASK_PIO = ((1 << ATA_BITS_PIO) - 1) << ATA_SHIFT_PIO, + ATA_MASK_MWDMA = ((1 << ATA_BITS_MWDMA) - 1) << ATA_SHIFT_MWDMA, + ATA_MASK_UDMA = ((1 << ATA_BITS_UDMA) - 1) << ATA_SHIFT_UDMA, /* size of buffer to pad xfers ending on unaligned boundaries */ ATA_DMA_PAD_SZ = 4, -- cgit v1.2.2 From dabaeff06cca86048cfa3f74ce59688bc3addba9 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Wed, 15 Mar 2006 23:17:26 +0000 Subject: [ARM] 3364/1: [cleanup] warning fix - definitions for enable_hlt and disable_hlt Patch from Ben Dooks The enable_hlt and disable_hlt should be declared in include/asm/setup.h. This fixes sparse errors from arch/arm/kernel/process.c Signed-off-by: Ben Dooks Signed-off-by: Russell King --- include/asm-arm/system.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include') diff --git a/include/asm-arm/system.h b/include/asm-arm/system.h index eb2de8c105..ec91d1ff03 100644 --- a/include/asm-arm/system.h +++ b/include/asm-arm/system.h @@ -415,6 +415,9 @@ static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size return ret; } +extern void disable_hlt(void); +extern void enable_hlt(void); + #endif /* __ASSEMBLY__ */ #define arch_align_stack(x) (x) -- cgit v1.2.2 From 92eb4602eb5c37db86cd9d2b1f4c8ca304fbc49f Mon Sep 17 00:00:00 2001 From: John Rose Date: Tue, 14 Mar 2006 17:46:45 -0600 Subject: [PATCH] powerpc: properly configure DDR/P5IOC children devs The dynamic add path for PCI Host Bridges can fail to configure children adapters under P5IOC controllers. It fails to properly fixup bus/device resources, and it fails to properly enable EEH. Both of these steps need to occur before any children devices are enabled in pci_bus_add_devices(). Signed-off-by: John Rose Signed-off-by: Paul Mackerras --- include/asm-powerpc/ppc-pci.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/asm-powerpc/ppc-pci.h b/include/asm-powerpc/ppc-pci.h index f80482c723..cf79bc7ebb 100644 --- a/include/asm-powerpc/ppc-pci.h +++ b/include/asm-powerpc/ppc-pci.h @@ -38,6 +38,7 @@ void *traverse_pci_devices(struct device_node *start, traverse_func pre, void pci_devs_phb_init(void); void pci_devs_phb_init_dynamic(struct pci_controller *phb); +int setup_phb(struct device_node *dev, struct pci_controller *phb); void __devinit scan_phb(struct pci_controller *hose); /* From rtas_pci.h */ -- cgit v1.2.2 From 243f196d572822214bb86522f28b30e096d67414 Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Thu, 16 Mar 2006 14:10:19 +0000 Subject: [ARM] 3366/1: Allow the 16bpp mode configuration in the CLCD control register Patch from Catalin Marinas Starting with PL111, the 5551 or 565 modes can be configured in the primecell's control register directly. This patch detects the required mode and sets the correct value. Signed-off-by: Catalin Marinas Signed-off-by: Russell King --- include/linux/amba/clcd.h | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/amba/clcd.h b/include/linux/amba/clcd.h index 6b8d73dc1a..9cf64b1b68 100644 --- a/include/linux/amba/clcd.h +++ b/include/linux/amba/clcd.h @@ -54,6 +54,7 @@ #define CNTL_LCDBPP4 (2 << 1) #define CNTL_LCDBPP8 (3 << 1) #define CNTL_LCDBPP16 (4 << 1) +#define CNTL_LCDBPP16_565 (6 << 1) #define CNTL_LCDBPP24 (5 << 1) #define CNTL_LCDBW (1 << 4) #define CNTL_LCDTFT (1 << 5) @@ -209,7 +210,16 @@ static inline void clcdfb_decode(struct clcd_fb *fb, struct clcd_regs *regs) val |= CNTL_LCDBPP8; break; case 16: - val |= CNTL_LCDBPP16; + /* + * PL110 cannot choose between 5551 and 565 modes in + * its control register + */ + if ((fb->dev->periphid & 0x000fffff) == 0x00041110) + val |= CNTL_LCDBPP16; + else if (fb->fb.var.green.length == 5) + val |= CNTL_LCDBPP16; + else + val |= CNTL_LCDBPP16_565; break; case 32: val |= CNTL_LCDBPP24; -- cgit v1.2.2 From 265a92856b17524c87da0258ac0d3cec80ae1d35 Mon Sep 17 00:00:00 2001 From: Alexey Kuznetsov Date: Fri, 17 Mar 2006 16:05:43 -0800 Subject: [NET]: Fix race condition in sk_wait_event(). It is broken, the condition is checked out of socket lock. It is wonderful the bug survived for so long time. [ This fixes bugzilla #6233: race condition in tcp_sendmsg when connection became established ] Signed-off-by: David S. Miller --- include/net/sock.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/net/sock.h b/include/net/sock.h index 30758035d6..f63d0d5671 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -478,9 +478,9 @@ static inline void sk_add_backlog(struct sock *sk, struct sk_buff *skb) rc = __condition; \ if (!rc) { \ *(__timeo) = schedule_timeout(*(__timeo)); \ - rc = __condition; \ } \ lock_sock(__sk); \ + rc = __condition; \ rc; \ }) -- cgit v1.2.2 From a3c4946db4fe64cb21b66a09e89890678aac6d65 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Mon, 13 Mar 2006 16:16:29 +0000 Subject: [MIPS] SB1: Fix interrupt disable hazard. The SB1 core has a three cycle interrupt disable hazard but we were wrongly treating it as fully interlocked. Signed-off-by: Ralf Baechle --- include/asm-mips/hazards.h | 180 ++++++++++++++++++++++++++------------------- 1 file changed, 103 insertions(+), 77 deletions(-) (limited to 'include') diff --git a/include/asm-mips/hazards.h b/include/asm-mips/hazards.h index 6111a0ce58..feb29a7938 100644 --- a/include/asm-mips/hazards.h +++ b/include/asm-mips/hazards.h @@ -3,7 +3,9 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2003, 2004 Ralf Baechle + * Copyright (C) 2003, 2004 Ralf Baechle + * Copyright (C) MIPS Technologies, Inc. + * written by Ralf Baechle */ #ifndef _ASM_HAZARDS_H #define _ASM_HAZARDS_H @@ -74,8 +76,7 @@ #define irq_disable_hazard _ehb -#elif defined(CONFIG_CPU_R10000) || defined(CONFIG_CPU_RM9000) || \ - defined(CONFIG_CPU_SB1) +#elif defined(CONFIG_CPU_R10000) || defined(CONFIG_CPU_RM9000) /* * R10000 rocks - all hazards handled in hardware, so this becomes a nobrainer. @@ -99,13 +100,13 @@ #else /* __ASSEMBLY__ */ __asm__( - " .macro _ssnop \n\t" - " sll $0, $0, 1 \n\t" - " .endm \n\t" - " \n\t" - " .macro _ehb \n\t" - " sll $0, $0, 3 \n\t" - " .endm \n\t"); + " .macro _ssnop \n" + " sll $0, $0, 1 \n" + " .endm \n" + " \n" + " .macro _ehb \n" + " sll $0, $0, 3 \n" + " .endm \n"); #ifdef CONFIG_CPU_RM9000 @@ -117,17 +118,21 @@ __asm__( #define mtc0_tlbw_hazard() \ __asm__ __volatile__( \ - ".set\tmips32\n\t" \ - "_ssnop; _ssnop; _ssnop; _ssnop\n\t" \ - ".set\tmips0") + " .set mips32 \n" \ + " _ssnop \n" \ + " _ssnop \n" \ + " _ssnop \n" \ + " _ssnop \n" \ + " .set mips0 \n") #define tlbw_use_hazard() \ __asm__ __volatile__( \ - ".set\tmips32\n\t" \ - "_ssnop; _ssnop; _ssnop; _ssnop\n\t" \ - ".set\tmips0") - -#define back_to_back_c0_hazard() do { } while (0) + " .set mips32 \n" \ + " _ssnop \n" \ + " _ssnop \n" \ + " _ssnop \n" \ + " _ssnop \n" \ + " .set mips0 \n") #else @@ -136,15 +141,25 @@ __asm__( */ #define mtc0_tlbw_hazard() \ __asm__ __volatile__( \ - ".set noreorder\n\t" \ - "nop; nop; nop; nop; nop; nop;\n\t" \ - ".set reorder\n\t") + " .set noreorder \n" \ + " nop \n" \ + " nop \n" \ + " nop \n" \ + " nop \n" \ + " nop \n" \ + " nop \n" \ + " .set reorder \n") #define tlbw_use_hazard() \ __asm__ __volatile__( \ - ".set noreorder\n\t" \ - "nop; nop; nop; nop; nop; nop;\n\t" \ - ".set reorder\n\t") + " .set noreorder \n" \ + " nop \n" \ + " nop \n" \ + " nop \n" \ + " nop \n" \ + " nop \n" \ + " nop \n" \ + " .set reorder \n") #endif @@ -156,49 +171,26 @@ __asm__( #ifdef CONFIG_CPU_MIPSR2 -__asm__( - " .macro\tirq_enable_hazard \n\t" - " _ehb \n\t" - " .endm \n\t" - " \n\t" - " .macro\tirq_disable_hazard \n\t" - " _ehb \n\t" - " .endm \n\t" - " \n\t" - " .macro\tback_to_back_c0_hazard \n\t" - " _ehb \n\t" - " .endm"); - -#define irq_enable_hazard() \ - __asm__ __volatile__( \ - "irq_enable_hazard") +__asm__(" .macro irq_enable_hazard \n" + " _ehb \n" + " .endm \n" + " \n" + " .macro irq_disable_hazard \n" + " _ehb \n" + " .endm \n"); -#define irq_disable_hazard() \ - __asm__ __volatile__( \ - "irq_disable_hazard") - -#define back_to_back_c0_hazard() \ - __asm__ __volatile__( \ - "back_to_back_c0_hazard") - -#elif defined(CONFIG_CPU_R10000) || defined(CONFIG_CPU_RM9000) || \ - defined(CONFIG_CPU_SB1) +#elif defined(CONFIG_CPU_R10000) || defined(CONFIG_CPU_RM9000) /* * R10000 rocks - all hazards handled in hardware, so this becomes a nobrainer. */ __asm__( - " .macro\tirq_enable_hazard \n\t" - " .endm \n\t" - " \n\t" - " .macro\tirq_disable_hazard \n\t" - " .endm"); - -#define irq_enable_hazard() do { } while (0) -#define irq_disable_hazard() do { } while (0) - -#define back_to_back_c0_hazard() do { } while (0) + " .macro irq_enable_hazard \n" + " .endm \n" + " \n" + " .macro irq_disable_hazard \n" + " .endm \n"); #else @@ -209,29 +201,63 @@ __asm__( */ __asm__( - " # \n\t" - " # There is a hazard but we do not care \n\t" - " # \n\t" - " .macro\tirq_enable_hazard \n\t" - " .endm \n\t" - " \n\t" - " .macro\tirq_disable_hazard \n\t" - " _ssnop; _ssnop; _ssnop \n\t" - " .endm"); + " # \n" + " # There is a hazard but we do not care \n" + " # \n" + " .macro\tirq_enable_hazard \n" + " .endm \n" + " \n" + " .macro\tirq_disable_hazard \n" + " _ssnop \n" + " _ssnop \n" + " _ssnop \n" + " .endm \n"); -#define irq_enable_hazard() do { } while (0) +#endif + +#define irq_enable_hazard() \ + __asm__ __volatile__("irq_enable_hazard") #define irq_disable_hazard() \ - __asm__ __volatile__( \ - "irq_disable_hazard") + __asm__ __volatile__("irq_disable_hazard") -#define back_to_back_c0_hazard() \ - __asm__ __volatile__( \ - " .set noreorder \n" \ - " nop; nop; nop \n" \ - " .set reorder \n") + +/* + * Back-to-back hazards - + * + * What is needed to separate a move to cp0 from a subsequent read from the + * same cp0 register? + */ +#ifdef CONFIG_CPU_MIPSR2 + +__asm__(" .macro back_to_back_c0_hazard \n" + " _ehb \n" + " .endm \n"); + +#elif defined(CONFIG_CPU_R10000) || defined(CONFIG_CPU_RM9000) || \ + defined(CONFIG_CPU_SB1) + +__asm__(" .macro back_to_back_c0_hazard \n" + " .endm \n"); + +#else + +__asm__(" .macro back_to_back_c0_hazard \n" + " .set noreorder \n" + " _ssnop \n" + " _ssnop \n" + " _ssnop \n" + " .set reorder \n" + " .endm"); #endif +#define back_to_back_c0_hazard() \ + __asm__ __volatile__("back_to_back_c0_hazard") + + +/* + * Instruction execution hazard + */ #ifdef CONFIG_CPU_MIPSR2 /* * gcc has a tradition of misscompiling the previous construct using the -- cgit v1.2.2 From de62893bc0725f8b5f0445250577cd7a10b2d8f8 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Mon, 13 Mar 2006 18:23:03 +0900 Subject: [MIPS] local_r4k_flush_cache_page fix If dcache_size != icache_size or dcache_size != scache_size, or set-associative cache, icache/scache does not flushed properly. Make blast_?cache_page_indexed() masks its index value correctly. Also, use physical address for physically indexed pcache/scache. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- include/asm-mips/cpu-features.h | 3 +++ include/asm-mips/cpu-info.h | 1 + include/asm-mips/r4kcache.h | 3 ++- 3 files changed, 6 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/asm-mips/cpu-features.h b/include/asm-mips/cpu-features.h index 78c9cc2735..3f2b6d9ac4 100644 --- a/include/asm-mips/cpu-features.h +++ b/include/asm-mips/cpu-features.h @@ -96,6 +96,9 @@ #ifndef cpu_has_ic_fills_f_dc #define cpu_has_ic_fills_f_dc (cpu_data[0].icache.flags & MIPS_CACHE_IC_F_DC) #endif +#ifndef cpu_has_pindexed_dcache +#define cpu_has_pindexed_dcache (cpu_data[0].dcache.flags & MIPS_CACHE_PINDEX) +#endif /* * I-Cache snoops remote store. This only matters on SMP. Some multiprocessors diff --git a/include/asm-mips/cpu-info.h b/include/asm-mips/cpu-info.h index d5cf519f8f..140be1c67d 100644 --- a/include/asm-mips/cpu-info.h +++ b/include/asm-mips/cpu-info.h @@ -39,6 +39,7 @@ struct cache_desc { #define MIPS_CACHE_ALIASES 0x00000004 /* Cache could have aliases */ #define MIPS_CACHE_IC_F_DC 0x00000008 /* Ic can refill from D-cache */ #define MIPS_IC_SNOOPS_REMOTE 0x00000010 /* Ic snoops remote stores */ +#define MIPS_CACHE_PINDEX 0x00000020 /* Physically indexed cache */ struct cpuinfo_mips { unsigned long udelay_val; diff --git a/include/asm-mips/r4kcache.h b/include/asm-mips/r4kcache.h index 9632c27dad..0bcb79a58e 100644 --- a/include/asm-mips/r4kcache.h +++ b/include/asm-mips/r4kcache.h @@ -257,7 +257,8 @@ static inline void blast_##pfx##cache##lsize##_page(unsigned long page) \ \ static inline void blast_##pfx##cache##lsize##_page_indexed(unsigned long page) \ { \ - unsigned long start = page; \ + unsigned long indexmask = current_cpu_data.desc.waysize - 1; \ + unsigned long start = INDEX_BASE + (page & indexmask); \ unsigned long end = start + PAGE_SIZE; \ unsigned long ws_inc = 1UL << current_cpu_data.desc.waybit; \ unsigned long ws_end = current_cpu_data.desc.ways << \ -- cgit v1.2.2 From 966f4406d903a4214fdc74bec54710c6232a95b8 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Wed, 15 Mar 2006 11:36:31 +0000 Subject: [MIPS] Work around bad code generation for . If a call to set_io_port_base() was being followed by usage of mips_io_port_base in the same function gcc was possibly using the old value due to some clever abuse of const. Adding a barrier will keep the optimization and result in correct code with latest gcc. Signed-off-by: Ralf Baechle --- include/asm-mips/io.h | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/asm-mips/io.h b/include/asm-mips/io.h index 8c011aa61a..ba1d7bbc15 100644 --- a/include/asm-mips/io.h +++ b/include/asm-mips/io.h @@ -4,7 +4,7 @@ * for more details. * * Copyright (C) 1994, 1995 Waldorf GmbH - * Copyright (C) 1994 - 2000 Ralf Baechle + * Copyright (C) 1994 - 2000, 06 Ralf Baechle * Copyright (C) 1999, 2000 Silicon Graphics, Inc. * Copyright (C) 2004, 2005 MIPS Technologies, Inc. All rights reserved. * Author: Maciej W. Rozycki @@ -103,8 +103,20 @@ */ extern const unsigned long mips_io_port_base; -#define set_io_port_base(base) \ - do { * (unsigned long *) &mips_io_port_base = (base); } while (0) +/* + * Gcc will generate code to load the value of mips_io_port_base after each + * function call which may be fairly wasteful in some cases. So we don't + * play quite by the book. We tell gcc mips_io_port_base is a long variable + * which solves the code generation issue. Now we need to violate the + * aliasing rules a little to make initialization possible and finally we + * will need the barrier() to fight side effects of the aliasing chat. + * This trickery will eventually collapse under gcc's optimizer. Oh well. + */ +static inline void set_io_port_base(unsigned long base) +{ + * (unsigned long *) &mips_io_port_base = base; + barrier(); +} /* * Thanks to James van Artsdalen for a better timing-fix than -- cgit v1.2.2 From a77f124294822203660b0926392b963cfa72fcf4 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 14 Mar 2006 23:47:35 +0000 Subject: [MIPS] Sibyte: Fix M_SCD_TIMER_INIT and M_SCD_TIMER_CNT wrong field width. From Dave Johnson : Field width should be 23 bits not 20 bits. Signed-off-by: Ralf Baechle --- include/asm-mips/sibyte/sb1250_scd.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/asm-mips/sibyte/sb1250_scd.h b/include/asm-mips/sibyte/sb1250_scd.h index a667bc14a7..f4178bdcfc 100644 --- a/include/asm-mips/sibyte/sb1250_scd.h +++ b/include/asm-mips/sibyte/sb1250_scd.h @@ -359,14 +359,15 @@ */ #define V_SCD_TIMER_FREQ 1000000 +#define V_SCD_TIMER_WIDTH 23 #define S_SCD_TIMER_INIT 0 -#define M_SCD_TIMER_INIT _SB_MAKEMASK(20,S_SCD_TIMER_INIT) +#define M_SCD_TIMER_INIT _SB_MAKEMASK(V_SCD_TIMER_WIDTH,S_SCD_TIMER_INIT) #define V_SCD_TIMER_INIT(x) _SB_MAKEVALUE(x,S_SCD_TIMER_INIT) #define G_SCD_TIMER_INIT(x) _SB_GETVALUE(x,S_SCD_TIMER_INIT,M_SCD_TIMER_INIT) #define S_SCD_TIMER_CNT 0 -#define M_SCD_TIMER_CNT _SB_MAKEMASK(20,S_SCD_TIMER_CNT) +#define M_SCD_TIMER_CNT _SB_MAKEMASK(V_SCD_TIMER_WIDTH,S_SCD_TIMER_CNT) #define V_SCD_TIMER_CNT(x) _SB_MAKEVALUE(x,S_SCD_TIMER_CNT) #define G_SCD_TIMER_CNT(x) _SB_GETVALUE(x,S_SCD_TIMER_CNT,M_SCD_TIMER_CNT) -- cgit v1.2.2 From a904f7478561464f9fe74929b81fec237b6ff4c3 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Wed, 15 Mar 2006 00:03:29 +0000 Subject: [MIPS] Sibyte: Fix race in sb1250_gettimeoffset(). From Dave Johnson : sb1250_gettimeoffset() simply reads the current cpu 0 timer remaining value, however once this counter reaches 0 and the interrupt is raised, it immediately resets and begins to count down again. If sb1250_gettimeoffset() is called on cpu 1 via do_gettimeofday() after the timer has reset but prior to cpu 0 processing the interrupt and taking write_seqlock() in timer_interrupt() it will return a full value (or close to it) causing time to jump backwards 1ms. Once cpu 0 handles the interrupt and timer_interrupt() gets far enough along it will jump forward 1ms. Fix this problem by implementing mips_hpt_*() on sb1250 using a spare timer unrelated to the existing periodic interrupt timers. It runs at 1Mhz with a full 23bit counter. This eliminated the custom do_gettimeoffset() for sb1250 and allowed use of the generic fixed_rate_gettimeoffset() using mips_hpt_*() and timerhi/timerlo. Signed-off-by: Ralf Baechle --- include/asm-mips/sibyte/sb1250.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/asm-mips/sibyte/sb1250.h b/include/asm-mips/sibyte/sb1250.h index a474c29cd7..b09e16c93c 100644 --- a/include/asm-mips/sibyte/sb1250.h +++ b/include/asm-mips/sibyte/sb1250.h @@ -45,8 +45,8 @@ extern unsigned int soc_type; extern unsigned int periph_rev; extern unsigned int zbbus_mhz; +extern void sb1250_hpt_setup(void); extern void sb1250_time_init(void); -extern unsigned long sb1250_gettimeoffset(void); extern void sb1250_mask_irq(int cpu, int irq); extern void sb1250_unmask_irq(int cpu, int irq); extern void sb1250_smp_finish(void); -- cgit v1.2.2 From 12a057321529df2fb650ac5f34dfd7abcca667df Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 18 Mar 2006 13:38:01 -0500 Subject: [PATCH] keep sync and async cfq_queue separate Signed-off-by: Al Viro --- include/linux/blkdev.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 860e7a485a..e19cb63108 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -58,7 +58,7 @@ struct cfq_io_context { * circular list of cfq_io_contexts belonging to a process io context */ struct list_head list; - struct cfq_queue *cfqq; + struct cfq_queue *cfqq[2]; void *key; struct io_context *ioc; -- cgit v1.2.2 From d9ff41879364cfca7c15abc20ae398e35de3f883 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 18 Mar 2006 13:51:22 -0500 Subject: [PATCH] make cfq_exit_queue() prune the cfq_io_context for that queue Signed-off-by: Al Viro --- include/linux/blkdev.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index e19cb63108..80518f7035 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -69,6 +69,8 @@ struct cfq_io_context { unsigned long ttime_samples; unsigned long ttime_mean; + struct list_head queue_list; + void (*dtor)(struct cfq_io_context *); void (*exit)(struct cfq_io_context *); }; -- cgit v1.2.2 From e17a9489b4a686bb5e9615e1d375c67619cb99c5 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 18 Mar 2006 13:21:20 -0500 Subject: [PATCH] stop elv_unregister() from rogering other iosched's data, fix locking Signed-off-by: Al Viro --- include/linux/elevator.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/elevator.h b/include/linux/elevator.h index 18cf1f3e11..f65766ef05 100644 --- a/include/linux/elevator.h +++ b/include/linux/elevator.h @@ -48,6 +48,7 @@ struct elevator_ops elevator_init_fn *elevator_init_fn; elevator_exit_fn *elevator_exit_fn; + void (*trim)(struct io_context *); }; #define ELV_NAME_MAX (16) -- cgit v1.2.2 From 483f4afc421435b7cfe5e88f74eea0b73a476d75 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 18 Mar 2006 18:34:37 -0500 Subject: [PATCH] fix sysfs interaction and lifetime rules handling for queues --- include/linux/blkdev.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 80518f7035..56bb6a4e15 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -406,8 +406,6 @@ struct request_queue struct blk_queue_tag *queue_tags; - atomic_t refcnt; - unsigned int nr_sorted; unsigned int in_flight; @@ -426,6 +424,8 @@ struct request_queue struct request pre_flush_rq, bar_rq, post_flush_rq; struct request *orig_bar_rq; unsigned int bi_size; + + struct mutex sysfs_lock; }; #define RQ_INACTIVE (-1) @@ -727,7 +727,7 @@ extern long nr_blockdev_pages(void); int blk_get_queue(request_queue_t *); request_queue_t *blk_alloc_queue(gfp_t); request_queue_t *blk_alloc_queue_node(gfp_t, int); -#define blk_put_queue(q) blk_cleanup_queue((q)) +extern void blk_put_queue(request_queue_t *); /* * tag stuff -- cgit v1.2.2 From 3d1ab40f4c20767afbd361b258a531d73e3e6fc2 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 18 Mar 2006 18:35:43 -0500 Subject: [PATCH] elevator_t lifetime rules and sysfs fixes --- include/linux/elevator.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/elevator.h b/include/linux/elevator.h index f65766ef05..4d0a80f13e 100644 --- a/include/linux/elevator.h +++ b/include/linux/elevator.h @@ -61,7 +61,7 @@ struct elevator_type struct list_head list; struct elevator_ops ops; struct elevator_type *elevator_type; - struct kobj_type *elevator_ktype; + struct attribute **elevator_attrs; char elevator_name[ELV_NAME_MAX]; struct module *elevator_owner; }; @@ -75,6 +75,7 @@ struct elevator_queue void *elevator_data; struct kobject kobj; struct elevator_type *elevator_type; + struct mutex sysfs_lock; }; /* @@ -141,6 +142,12 @@ enum { ELV_MQUEUE_MUST, }; +struct elv_fs_entry { + struct attribute attr; + ssize_t (*show)(elevator_t *, char *); + ssize_t (*store)(elevator_t *, const char *, size_t); +}; + #define rq_end_sector(rq) ((rq)->sector + (rq)->nr_sectors) #endif -- cgit v1.2.2 From e572ec7e4e432de7ecf7bd2e62117646fa64e518 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 18 Mar 2006 22:27:18 -0500 Subject: [PATCH] fix rmmod problems with elevator attributes, clean them up --- include/linux/elevator.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'include') diff --git a/include/linux/elevator.h b/include/linux/elevator.h index 4d0a80f13e..ad133fcfb2 100644 --- a/include/linux/elevator.h +++ b/include/linux/elevator.h @@ -53,6 +53,12 @@ struct elevator_ops #define ELV_NAME_MAX (16) +struct elv_fs_entry { + struct attribute attr; + ssize_t (*show)(elevator_t *, char *); + ssize_t (*store)(elevator_t *, const char *, size_t); +}; + /* * identifies an elevator type, such as AS or deadline */ @@ -61,7 +67,7 @@ struct elevator_type struct list_head list; struct elevator_ops ops; struct elevator_type *elevator_type; - struct attribute **elevator_attrs; + struct elv_fs_entry *elevator_attrs; char elevator_name[ELV_NAME_MAX]; struct module *elevator_owner; }; @@ -142,12 +148,6 @@ enum { ELV_MQUEUE_MUST, }; -struct elv_fs_entry { - struct attribute attr; - ssize_t (*show)(elevator_t *, char *); - ssize_t (*store)(elevator_t *, const char *, size_t); -}; - #define rq_end_sector(rq) ((rq)->sector + (rq)->nr_sectors) #endif -- cgit v1.2.2 From c7c694d196a39af6e644e24279953d04f30362db Mon Sep 17 00:00:00 2001 From: Ralf Baechle DL5RB Date: Sun, 19 Mar 2006 13:20:06 -0800 Subject: [AX.25]: Fix potencial memory hole. If the AX.25 dialect chosen by the sysadmin is set to DAMA master / 3 (or DAMA slave / 2, if CONFIG_AX25_DAMA_SLAVE=n) ax25_kick() will fall through the switch statement without calling ax25_send_iframe() or any other function that would eventually free skbn thus leaking the packet. Fix by restricting the sysctl inferface to allow only actually supported AX.25 dialects. The system administration mistake needed for this to happen is rather unlikely, so this is an uncritical hole. Coverity #651. Signed-off-by: Ralf Baechle DL5RB Signed-off-by: David S. Miller --- include/net/ax25.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/net/ax25.h b/include/net/ax25.h index 2250a18b0c..d052b221db 100644 --- a/include/net/ax25.h +++ b/include/net/ax25.h @@ -110,8 +110,15 @@ enum { enum { AX25_PROTO_STD_SIMPLEX, AX25_PROTO_STD_DUPLEX, +#ifdef CONFIG_AX25_DAMA_SLAVE AX25_PROTO_DAMA_SLAVE, - AX25_PROTO_DAMA_MASTER +#ifdef CONFIG_AX25_DAMA_MASTER + AX25_PROTO_DAMA_MASTER, +#define AX25_PROTO_MAX AX25_PROTO_DAMA_MASTER +#endif +#endif + __AX25_PROTO_MAX, + AX25_PROTO_MAX = __AX25_PROTO_MAX -1 }; enum { -- cgit v1.2.2 From 4a29cc2e503b33a1e96db4c3f9a94165f153f259 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Sun, 19 Mar 2006 13:21:12 -0800 Subject: [TG3]: 40-bit DMA workaround part 2 The 40-bit DMA workaround recently implemented for 5714, 5715, and 5780 needs to be expanded because there may be other tg3 devices behind the EPB Express to PCIX bridge in the 5780 class device. For example, some 4-port card or mother board designs have 5704 behind the 5714. All devices behind the EPB require the 40-bit DMA workaround. Thanks to Chris Elmquist again for reporting the problem and testing the patch. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- include/linux/pci_ids.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 1709b5009d..751eea58bd 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -1365,6 +1365,7 @@ #define PCI_DEVICE_ID_SERVERWORKS_HE 0x0008 #define PCI_DEVICE_ID_SERVERWORKS_LE 0x0009 #define PCI_DEVICE_ID_SERVERWORKS_GCNB_LE 0x0017 +#define PCI_DEVICE_ID_SERVERWORKS_EPB 0x0103 #define PCI_DEVICE_ID_SERVERWORKS_OSB4 0x0200 #define PCI_DEVICE_ID_SERVERWORKS_CSB5 0x0201 #define PCI_DEVICE_ID_SERVERWORKS_CSB6 0x0203 -- cgit v1.2.2 From 74bf4312fff083ab25c3f357cc653ada7995e5f6 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 31 Jan 2006 18:29:18 -0800 Subject: [SPARC64]: Move away from virtual page tables, part 1. We now use the TSB hardware assist features of the UltraSPARC MMUs. SMP is currently knowingly broken, we need to find another place to store the per-cpu base pointers. We hid them away in the TSB base register, and that obviously will not work any more :-) Another known broken case is non-8KB base page size. Also noticed that flush_tlb_all() is not referenced anywhere, only the internal __flush_tlb_all() (local cpu only) is used by the sparc64 port, so we can get rid of flush_tlb_all(). The kernel gets it's own 8KB TSB (swapper_tsb) and each address space gets it's own private 8K TSB. Later we can add code to dynamically increase the size of per-process TSB as the RSS grows. An 8KB TSB is good enough for up to about a 4MB RSS, after which the TSB starts to incur many capacity and conflict misses. We even accumulate OBP translations into the kernel TSB. Another area for refinement is large page size support. We could use a secondary address space TSB to handle those. Signed-off-by: David S. Miller --- include/asm-sparc64/mmu.h | 1 + include/asm-sparc64/mmu_context.h | 46 +++-------- include/asm-sparc64/pgalloc.h | 1 + include/asm-sparc64/pgtable.h | 9 +-- include/asm-sparc64/processor.h | 14 +--- include/asm-sparc64/tlbflush.h | 25 ++++-- include/asm-sparc64/tsb.h | 165 ++++++++++++++++++++++++++++++++++++++ 7 files changed, 204 insertions(+), 57 deletions(-) create mode 100644 include/asm-sparc64/tsb.h (limited to 'include') diff --git a/include/asm-sparc64/mmu.h b/include/asm-sparc64/mmu.h index 8627eed6e8..36384cf7fa 100644 --- a/include/asm-sparc64/mmu.h +++ b/include/asm-sparc64/mmu.h @@ -92,6 +92,7 @@ typedef struct { unsigned long sparc64_ctx_val; + unsigned long *sparc64_tsb; } mm_context_t; #endif /* !__ASSEMBLY__ */ diff --git a/include/asm-sparc64/mmu_context.h b/include/asm-sparc64/mmu_context.h index 57ee7b3061..34640a370a 100644 --- a/include/asm-sparc64/mmu_context.h +++ b/include/asm-sparc64/mmu_context.h @@ -25,7 +25,13 @@ extern void get_new_mmu_context(struct mm_struct *mm); * This just needs to set mm->context to an invalid context. */ #define init_new_context(__tsk, __mm) \ - (((__mm)->context.sparc64_ctx_val = 0UL), 0) +({ unsigned long __pg = get_zeroed_page(GFP_KERNEL); \ + (__mm)->context.sparc64_ctx_val = 0UL; \ + (__mm)->context.sparc64_tsb = \ + (unsigned long *) __pg; \ + (__pg ? 0 : -ENOMEM); \ +}) + /* Destroy a dead context. This occurs when mmput drops the * mm_users count to zero, the mmaps have been released, and @@ -35,7 +41,8 @@ extern void get_new_mmu_context(struct mm_struct *mm); * this task if valid. */ #define destroy_context(__mm) \ -do { spin_lock(&ctx_alloc_lock); \ +do { free_page((unsigned long)(__mm)->context.sparc64_tsb); \ + spin_lock(&ctx_alloc_lock); \ if (CTX_VALID((__mm)->context)) { \ unsigned long nr = CTX_NRBITS((__mm)->context); \ mmu_context_bmap[nr>>6] &= ~(1UL << (nr & 63)); \ @@ -43,35 +50,7 @@ do { spin_lock(&ctx_alloc_lock); \ spin_unlock(&ctx_alloc_lock); \ } while(0) -/* Reload the two core values used by TLB miss handler - * processing on sparc64. They are: - * 1) The physical address of mm->pgd, when full page - * table walks are necessary, this is where the - * search begins. - * 2) A "PGD cache". For 32-bit tasks only pgd[0] is - * ever used since that maps the entire low 4GB - * completely. To speed up TLB miss processing we - * make this value available to the handlers. This - * decreases the amount of memory traffic incurred. - */ -#define reload_tlbmiss_state(__tsk, __mm) \ -do { \ - register unsigned long paddr asm("o5"); \ - register unsigned long pgd_cache asm("o4"); \ - paddr = __pa((__mm)->pgd); \ - pgd_cache = 0UL; \ - if (task_thread_info(__tsk)->flags & _TIF_32BIT) \ - pgd_cache = get_pgd_cache((__mm)->pgd); \ - __asm__ __volatile__("wrpr %%g0, 0x494, %%pstate\n\t" \ - "mov %3, %%g4\n\t" \ - "mov %0, %%g7\n\t" \ - "stxa %1, [%%g4] %2\n\t" \ - "membar #Sync\n\t" \ - "wrpr %%g0, 0x096, %%pstate" \ - : /* no outputs */ \ - : "r" (paddr), "r" (pgd_cache),\ - "i" (ASI_DMMU), "i" (TSB_REG)); \ -} while(0) +extern unsigned long tsb_context_switch(unsigned long pgd_pa, unsigned long *tsb); /* Set MMU context in the actual hardware. */ #define load_secondary_context(__mm) \ @@ -101,7 +80,8 @@ static inline void switch_mm(struct mm_struct *old_mm, struct mm_struct *mm, str if (!ctx_valid || (old_mm != mm)) { load_secondary_context(mm); - reload_tlbmiss_state(tsk, mm); + tsb_context_switch(__pa(mm->pgd), + mm->context.sparc64_tsb); } /* Even if (mm == old_mm) we _must_ check @@ -139,7 +119,7 @@ static inline void activate_mm(struct mm_struct *active_mm, struct mm_struct *mm load_secondary_context(mm); __flush_tlb_mm(CTX_HWBITS(mm->context), SECONDARY_CONTEXT); - reload_tlbmiss_state(current, mm); + tsb_context_switch(__pa(mm->pgd), mm->context.sparc64_tsb); } #endif /* !(__ASSEMBLY__) */ diff --git a/include/asm-sparc64/pgalloc.h b/include/asm-sparc64/pgalloc.h index a96067cca9..baf59c00ea 100644 --- a/include/asm-sparc64/pgalloc.h +++ b/include/asm-sparc64/pgalloc.h @@ -61,6 +61,7 @@ static __inline__ void free_pgd_slow(pgd_t *pgd) free_page((unsigned long)pgd); } +/* XXX This crap can die, no longer using virtual page tables... */ #ifdef DCACHE_ALIASING_POSSIBLE #define VPTE_COLOR(address) (((address) >> (PAGE_SHIFT + 10)) & 1UL) #define DCACHE_COLOR(address) (((address) >> PAGE_SHIFT) & 1UL) diff --git a/include/asm-sparc64/pgtable.h b/include/asm-sparc64/pgtable.h index f0a9b44d3e..f3ba1e0581 100644 --- a/include/asm-sparc64/pgtable.h +++ b/include/asm-sparc64/pgtable.h @@ -25,7 +25,8 @@ #include /* The kernel image occupies 0x4000000 to 0x1000000 (4MB --> 32MB). - * The page copy blockops can use 0x2000000 to 0x10000000. + * The page copy blockops can use 0x2000000 to 0x4000000. + * The TSB is mapped in the 0x4000000 to 0x6000000 range. * The PROM resides in an area spanning 0xf0000000 to 0x100000000. * The vmalloc area spans 0x100000000 to 0x200000000. * Since modules need to be in the lowest 32-bits of the address space, @@ -34,6 +35,7 @@ * 0x400000000. */ #define TLBTEMP_BASE _AC(0x0000000002000000,UL) +#define TSBMAP_BASE _AC(0x0000000004000000,UL) #define MODULES_VADDR _AC(0x0000000010000000,UL) #define MODULES_LEN _AC(0x00000000e0000000,UL) #define MODULES_END _AC(0x00000000f0000000,UL) @@ -296,11 +298,6 @@ static inline pte_t pte_modify(pte_t orig_pte, pgprot_t new_prot) /* to find an entry in a kernel page-table-directory */ #define pgd_offset_k(address) pgd_offset(&init_mm, address) -/* extract the pgd cache used for optimizing the tlb miss - * slow path when executing 32-bit compat processes - */ -#define get_pgd_cache(pgd) ((unsigned long) pgd_val(*pgd) << 11) - /* Find an entry in the second-level page table.. */ #define pmd_offset(pudp, address) \ ((pmd_t *) pud_page(*(pudp)) + \ diff --git a/include/asm-sparc64/processor.h b/include/asm-sparc64/processor.h index cd8d9b4c86..b3889f3f94 100644 --- a/include/asm-sparc64/processor.h +++ b/include/asm-sparc64/processor.h @@ -28,6 +28,8 @@ * User lives in his very own context, and cannot reference us. Note * that TASK_SIZE is a misnomer, it really gives maximum user virtual * address that the kernel will allocate out. + * + * XXX No longer using virtual page tables, kill this upper limit... */ #define VA_BITS 44 #ifndef __ASSEMBLY__ @@ -37,18 +39,6 @@ #endif #define TASK_SIZE ((unsigned long)-VPTE_SIZE) -/* - * The vpte base must be able to hold the entire vpte, half - * of which lives above, and half below, the base. And it - * is placed as close to the highest address range as possible. - */ -#define VPTE_BASE_SPITFIRE (-(VPTE_SIZE/2)) -#if 1 -#define VPTE_BASE_CHEETAH VPTE_BASE_SPITFIRE -#else -#define VPTE_BASE_CHEETAH 0xffe0000000000000 -#endif - #ifndef __ASSEMBLY__ typedef struct { diff --git a/include/asm-sparc64/tlbflush.h b/include/asm-sparc64/tlbflush.h index 3ef9909ac3..9ad5d9c51d 100644 --- a/include/asm-sparc64/tlbflush.h +++ b/include/asm-sparc64/tlbflush.h @@ -5,6 +5,11 @@ #include #include +/* TSB flush operations. */ +struct mmu_gather; +extern void flush_tsb_kernel_range(unsigned long start, unsigned long end); +extern void flush_tsb_user(struct mmu_gather *mp); + /* TLB flush operations. */ extern void flush_tlb_pending(void); @@ -14,28 +19,36 @@ extern void flush_tlb_pending(void); #define flush_tlb_page(vma,addr) flush_tlb_pending() #define flush_tlb_mm(mm) flush_tlb_pending() +/* Local cpu only. */ extern void __flush_tlb_all(void); + extern void __flush_tlb_page(unsigned long context, unsigned long page, unsigned long r); extern void __flush_tlb_kernel_range(unsigned long start, unsigned long end); #ifndef CONFIG_SMP -#define flush_tlb_all() __flush_tlb_all() #define flush_tlb_kernel_range(start,end) \ - __flush_tlb_kernel_range(start,end) +do { flush_tsb_kernel_range(start,end); \ + __flush_tlb_kernel_range(start,end); \ +} while (0) #else /* CONFIG_SMP */ -extern void smp_flush_tlb_all(void); extern void smp_flush_tlb_kernel_range(unsigned long start, unsigned long end); -#define flush_tlb_all() smp_flush_tlb_all() #define flush_tlb_kernel_range(start, end) \ - smp_flush_tlb_kernel_range(start, end) +do { flush_tsb_kernel_range(start,end); \ + smp_flush_tlb_kernel_range(start, end); \ +} while (0) #endif /* ! CONFIG_SMP */ -extern void flush_tlb_pgtables(struct mm_struct *, unsigned long, unsigned long); +static inline void flush_tlb_pgtables(struct mm_struct *mm, unsigned long start, unsigned long end) +{ + /* We don't use virtual page tables for TLB miss processing + * any more. Nowadays we use the TSB. + */ +} #endif /* _SPARC64_TLBFLUSH_H */ diff --git a/include/asm-sparc64/tsb.h b/include/asm-sparc64/tsb.h new file mode 100644 index 0000000000..03d272e0e4 --- /dev/null +++ b/include/asm-sparc64/tsb.h @@ -0,0 +1,165 @@ +#ifndef _SPARC64_TSB_H +#define _SPARC64_TSB_H + +/* The sparc64 TSB is similar to the powerpc hashtables. It's a + * power-of-2 sized table of TAG/PTE pairs. The cpu precomputes + * pointers into this table for 8K and 64K page sizes, and also a + * comparison TAG based upon the virtual address and context which + * faults. + * + * TLB miss trap handler software does the actual lookup via something + * of the form: + * + * ldxa [%g0] ASI_{D,I}MMU_TSB_8KB_PTR, %g1 + * ldxa [%g0] ASI_{D,I}MMU, %g6 + * ldda [%g1] ASI_NUCLEUS_QUAD_LDD, %g4 + * cmp %g4, %g6 + * bne,pn %xcc, tsb_miss_{d,i}tlb + * mov FAULT_CODE_{D,I}TLB, %g3 + * stxa %g5, [%g0] ASI_{D,I}TLB_DATA_IN + * retry + * + + * Each 16-byte slot of the TSB is the 8-byte tag and then the 8-byte + * PTE. The TAG is of the same layout as the TLB TAG TARGET mmu + * register which is: + * + * ------------------------------------------------- + * | - | CONTEXT | - | VADDR bits 63:22 | + * ------------------------------------------------- + * 63 61 60 48 47 42 41 0 + * + * Like the powerpc hashtables we need to use locking in order to + * synchronize while we update the entries. PTE updates need locking + * as well. + * + * We need to carefully choose a lock bits for the TSB entry. We + * choose to use bit 47 in the tag. Also, since we never map anything + * at page zero in context zero, we use zero as an invalid tag entry. + * When the lock bit is set, this forces a tag comparison failure. + * + * Currently, we allocate an 8K TSB per-process and we use it for both + * I-TLB and D-TLB misses. Perhaps at some point we'll add code that + * monitors the number of active pages in the process as we get + * major/minor faults, and grow the TSB in response. The only trick + * in implementing that is synchronizing the freeing of the old TSB + * wrt. parallel TSB updates occuring on other processors. On + * possible solution is to use RCU for the freeing of the TSB. + */ + +#define TSB_TAG_LOCK (1 << (47 - 32)) + +#define TSB_MEMBAR membar #StoreStore + +#define TSB_LOCK_TAG(TSB, REG1, REG2) \ +99: lduwa [TSB] ASI_N, REG1; \ + sethi %hi(TSB_TAG_LOCK), REG2;\ + andcc REG1, REG2, %g0; \ + bne,pn %icc, 99b; \ + nop; \ + casa [TSB] ASI_N, REG1, REG2;\ + cmp REG1, REG2; \ + bne,pn %icc, 99b; \ + nop; \ + TSB_MEMBAR + +#define TSB_WRITE(TSB, TTE, TAG) \ + stx TTE, [TSB + 0x08]; \ + TSB_MEMBAR; \ + stx TAG, [TSB + 0x00]; + + /* Do a kernel page table walk. Leaves physical PTE pointer in + * REG1. Jumps to FAIL_LABEL on early page table walk termination. + * VADDR will not be clobbered, but REG2 will. + */ +#define KERN_PGTABLE_WALK(VADDR, REG1, REG2, FAIL_LABEL) \ + sethi %hi(swapper_pg_dir), REG1; \ + or REG1, %lo(swapper_pg_dir), REG1; \ + sllx VADDR, 64 - (PGDIR_SHIFT + PGDIR_BITS), REG2; \ + srlx REG2, 64 - PAGE_SHIFT, REG2; \ + andn REG2, 0x3, REG2; \ + lduw [REG1 + REG2], REG1; \ + brz,pn REG1, FAIL_LABEL; \ + sllx VADDR, 64 - (PMD_SHIFT + PMD_BITS), REG2; \ + srlx REG2, 64 - PAGE_SHIFT, REG2; \ + sllx REG1, 11, REG1; \ + andn REG2, 0x3, REG2; \ + lduwa [REG1 + REG2] ASI_PHYS_USE_EC, REG1; \ + brz,pn REG1, FAIL_LABEL; \ + sllx VADDR, 64 - PMD_SHIFT, REG2; \ + srlx REG2, 64 - PAGE_SHIFT, REG2; \ + sllx REG1, 11, REG1; \ + andn REG2, 0x7, REG2; \ + add REG1, REG2, REG1; + + /* Do a user page table walk in MMU globals. Leaves physical PTE + * pointer in REG1. Jumps to FAIL_LABEL on early page table walk + * termination. Physical base of page tables is in PHYS_PGD which + * will not be modified. + * + * VADDR will not be clobbered, but REG1 and REG2 will. + */ +#define USER_PGTABLE_WALK_TL1(VADDR, PHYS_PGD, REG1, REG2, FAIL_LABEL) \ + sllx VADDR, 64 - (PGDIR_SHIFT + PGDIR_BITS), REG2; \ + srlx REG2, 64 - PAGE_SHIFT, REG2; \ + andn REG2, 0x3, REG2; \ + lduwa [PHYS_PGD + REG2] ASI_PHYS_USE_EC, REG1; \ + brz,pn REG1, FAIL_LABEL; \ + sllx VADDR, 64 - (PMD_SHIFT + PMD_BITS), REG2; \ + srlx REG2, 64 - PAGE_SHIFT, REG2; \ + sllx REG1, 11, REG1; \ + andn REG2, 0x3, REG2; \ + lduwa [REG1 + REG2] ASI_PHYS_USE_EC, REG1; \ + brz,pn REG1, FAIL_LABEL; \ + sllx VADDR, 64 - PMD_SHIFT, REG2; \ + srlx REG2, 64 - PAGE_SHIFT, REG2; \ + sllx REG1, 11, REG1; \ + andn REG2, 0x7, REG2; \ + add REG1, REG2, REG1; + +/* Lookup a OBP mapping on VADDR in the prom_trans[] table at TL>0. + * If no entry is found, FAIL_LABEL will be branched to. On success + * the resulting PTE value will be left in REG1. VADDR is preserved + * by this routine. + */ +#define OBP_TRANS_LOOKUP(VADDR, REG1, REG2, REG3, FAIL_LABEL) \ + sethi %hi(prom_trans), REG1; \ + or REG1, %lo(prom_trans), REG1; \ +97: ldx [REG1 + 0x00], REG2; \ + brz,pn REG2, FAIL_LABEL; \ + nop; \ + ldx [REG1 + 0x08], REG3; \ + add REG2, REG3, REG3; \ + cmp REG2, VADDR; \ + bgu,pt %xcc, 98f; \ + cmp VADDR, REG3; \ + bgeu,pt %xcc, 98f; \ + ldx [REG1 + 0x10], REG3; \ + sub VADDR, REG2, REG2; \ + ba,pt %xcc, 99f; \ + add REG3, REG2, REG1; \ +98: ba,pt %xcc, 97b; \ + add REG1, (3 * 8), REG1; \ +99: + + /* Do a kernel TSB lookup at tl>0 on VADDR+TAG, branch to OK_LABEL + * on TSB hit. REG1, REG2, REG3, and REG4 are used as temporaries + * and the found TTE will be left in REG1. REG3 and REG4 must + * be an even/odd pair of registers. + * + * VADDR and TAG will be preserved and not clobbered by this macro. + */ + /* XXX non-8K base page size support... */ +#define KERN_TSB_LOOKUP_TL1(VADDR, TAG, REG1, REG2, REG3, REG4, OK_LABEL) \ + sethi %hi(swapper_tsb), REG1; \ + or REG1, %lo(swapper_tsb), REG1; \ + srlx VADDR, 13, REG2; \ + and REG2, (512 - 1), REG2; \ + sllx REG2, 4, REG2; \ + add REG1, REG2, REG2; \ + ldda [REG2] ASI_NUCLEUS_QUAD_LDD, REG3; \ + cmp REG3, TAG; \ + be,a,pt %xcc, OK_LABEL; \ + mov REG4, REG1; + +#endif /* !(_SPARC64_TSB_H) */ -- cgit v1.2.2 From 05e28f9de65a38bb0c769080e91b6976e7e1e70c Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 31 Jan 2006 18:30:13 -0800 Subject: [SPARC64]: No need to D-cache color page tables any longer. Unlike the virtual page tables, the new TSB scheme does not require this ugly hack. Signed-off-by: David S. Miller --- include/asm-sparc64/cpudata.h | 5 ++- include/asm-sparc64/pgalloc.h | 101 +++++++++++++++++++----------------------- 2 files changed, 49 insertions(+), 57 deletions(-) (limited to 'include') diff --git a/include/asm-sparc64/cpudata.h b/include/asm-sparc64/cpudata.h index 74de79dca9..45a9a2cfaf 100644 --- a/include/asm-sparc64/cpudata.h +++ b/include/asm-sparc64/cpudata.h @@ -20,8 +20,9 @@ typedef struct { /* Dcache line 2 */ unsigned int pgcache_size; unsigned int __pad1; - unsigned long *pte_cache[2]; + unsigned long *pte_cache; unsigned long *pgd_cache; + unsigned long __pad2; /* Dcache line 3, rarely used */ unsigned int dcache_size; @@ -30,8 +31,8 @@ typedef struct { unsigned int icache_line_size; unsigned int ecache_size; unsigned int ecache_line_size; - unsigned int __pad2; unsigned int __pad3; + unsigned int __pad4; } cpuinfo_sparc; DECLARE_PER_CPU(cpuinfo_sparc, __cpu_data); diff --git a/include/asm-sparc64/pgalloc.h b/include/asm-sparc64/pgalloc.h index baf59c00ea..ecea1bbdc1 100644 --- a/include/asm-sparc64/pgalloc.h +++ b/include/asm-sparc64/pgalloc.h @@ -19,16 +19,15 @@ #else extern struct pgtable_cache_struct { unsigned long *pgd_cache; - unsigned long *pte_cache[2]; + unsigned long *pte_cache; unsigned int pgcache_size; } pgt_quicklists; #endif #define pgd_quicklist (pgt_quicklists.pgd_cache) -#define pmd_quicklist ((unsigned long *)0) #define pte_quicklist (pgt_quicklists.pte_cache) #define pgtable_cache_size (pgt_quicklists.pgcache_size) -static __inline__ void free_pgd_fast(pgd_t *pgd) +static inline void free_pgd_fast(pgd_t *pgd) { preempt_disable(); *(unsigned long *)pgd = (unsigned long) pgd_quicklist; @@ -37,7 +36,7 @@ static __inline__ void free_pgd_fast(pgd_t *pgd) preempt_enable(); } -static __inline__ pgd_t *get_pgd_fast(void) +static inline pgd_t *get_pgd_fast(void) { unsigned long *ret; @@ -56,47 +55,35 @@ static __inline__ pgd_t *get_pgd_fast(void) return (pgd_t *)ret; } -static __inline__ void free_pgd_slow(pgd_t *pgd) +static inline void free_pgd_slow(pgd_t *pgd) { free_page((unsigned long)pgd); } -/* XXX This crap can die, no longer using virtual page tables... */ -#ifdef DCACHE_ALIASING_POSSIBLE -#define VPTE_COLOR(address) (((address) >> (PAGE_SHIFT + 10)) & 1UL) -#define DCACHE_COLOR(address) (((address) >> PAGE_SHIFT) & 1UL) -#else -#define VPTE_COLOR(address) 0 -#define DCACHE_COLOR(address) 0 -#endif - #define pud_populate(MM, PUD, PMD) pud_set(PUD, PMD) -static __inline__ pmd_t *pmd_alloc_one_fast(struct mm_struct *mm, unsigned long address) +static inline pmd_t *pmd_alloc_one_fast(void) { unsigned long *ret; - int color = 0; preempt_disable(); - if (pte_quicklist[color] == NULL) - color = 1; - - if((ret = (unsigned long *)pte_quicklist[color]) != NULL) { - pte_quicklist[color] = (unsigned long *)(*ret); + ret = (unsigned long *) pte_quicklist; + if (likely(ret)) { + pte_quicklist = (unsigned long *)(*ret); ret[0] = 0; pgtable_cache_size--; } preempt_enable(); - return (pmd_t *)ret; + return (pmd_t *) ret; } -static __inline__ pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address) +static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address) { pmd_t *pmd; - pmd = pmd_alloc_one_fast(mm, address); - if (!pmd) { + pmd = pmd_alloc_one_fast(); + if (unlikely(!pmd)) { pmd = (pmd_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT); if (pmd) memset(pmd, 0, PAGE_SIZE); @@ -104,18 +91,16 @@ static __inline__ pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addre return pmd; } -static __inline__ void free_pmd_fast(pmd_t *pmd) +static inline void free_pmd_fast(pmd_t *pmd) { - unsigned long color = DCACHE_COLOR((unsigned long)pmd); - preempt_disable(); - *(unsigned long *)pmd = (unsigned long) pte_quicklist[color]; - pte_quicklist[color] = (unsigned long *) pmd; + *(unsigned long *)pmd = (unsigned long) pte_quicklist; + pte_quicklist = (unsigned long *) pmd; pgtable_cache_size++; preempt_enable(); } -static __inline__ void free_pmd_slow(pmd_t *pmd) +static inline void free_pmd_slow(pmd_t *pmd) { free_page((unsigned long)pmd); } @@ -124,48 +109,54 @@ static __inline__ void free_pmd_slow(pmd_t *pmd) #define pmd_populate(MM,PMD,PTE_PAGE) \ pmd_populate_kernel(MM,PMD,page_address(PTE_PAGE)) -extern pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address); - -static inline struct page * -pte_alloc_one(struct mm_struct *mm, unsigned long addr) -{ - pte_t *pte = pte_alloc_one_kernel(mm, addr); - - if (pte) - return virt_to_page(pte); - - return NULL; -} - -static __inline__ pte_t *pte_alloc_one_fast(struct mm_struct *mm, unsigned long address) +static inline pte_t *pte_alloc_one_fast(void) { - unsigned long color = VPTE_COLOR(address); unsigned long *ret; preempt_disable(); - if((ret = (unsigned long *)pte_quicklist[color]) != NULL) { - pte_quicklist[color] = (unsigned long *)(*ret); + ret = (unsigned long *) pte_quicklist; + if (likely(ret)) { + pte_quicklist = (unsigned long *)(*ret); ret[0] = 0; pgtable_cache_size--; } preempt_enable(); - return (pte_t *)ret; + + return (pte_t *) ret; +} + +static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) +{ + pte_t *ptep = pte_alloc_one_fast(); + + if (likely(ptep)) + return ptep; + + return (pte_t *) get_zeroed_page(GFP_KERNEL|__GFP_REPEAT); } -static __inline__ void free_pte_fast(pte_t *pte) +static inline struct page *pte_alloc_one(struct mm_struct *mm, unsigned long addr) { - unsigned long color = DCACHE_COLOR((unsigned long)pte); + pte_t *pte = pte_alloc_one_fast(); + if (likely(pte)) + return virt_to_page(pte); + + return alloc_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, 0); +} + +static inline void free_pte_fast(pte_t *pte) +{ preempt_disable(); - *(unsigned long *)pte = (unsigned long) pte_quicklist[color]; - pte_quicklist[color] = (unsigned long *) pte; + *(unsigned long *)pte = (unsigned long) pte_quicklist; + pte_quicklist = (unsigned long *) pte; pgtable_cache_size++; preempt_enable(); } -static __inline__ void free_pte_slow(pte_t *pte) +static inline void free_pte_slow(pte_t *pte) { - free_page((unsigned long)pte); + free_page((unsigned long) pte); } static inline void pte_free_kernel(pte_t *pte) -- cgit v1.2.2 From 3c936465249f863f322154ff1aaa628b84ee5750 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 31 Jan 2006 18:30:27 -0800 Subject: [SPARC64]: Kill pgtable quicklists and use SLAB. Taking a nod from the powerpc port. With the per-cpu caching of both the page allocator and SLAB, the pgtable quicklist scheme becomes relatively silly and primitive. Signed-off-by: David S. Miller --- include/asm-sparc64/cpudata.h | 9 +-- include/asm-sparc64/pgalloc.h | 158 ++++++++---------------------------------- include/asm-sparc64/pgtable.h | 7 +- 3 files changed, 29 insertions(+), 145 deletions(-) (limited to 'include') diff --git a/include/asm-sparc64/cpudata.h b/include/asm-sparc64/cpudata.h index 45a9a2cfaf..f7c0faede8 100644 --- a/include/asm-sparc64/cpudata.h +++ b/include/asm-sparc64/cpudata.h @@ -17,14 +17,7 @@ typedef struct { unsigned long clock_tick; /* %tick's per second */ unsigned long udelay_val; - /* Dcache line 2 */ - unsigned int pgcache_size; - unsigned int __pad1; - unsigned long *pte_cache; - unsigned long *pgd_cache; - unsigned long __pad2; - - /* Dcache line 3, rarely used */ + /* Dcache line 2, rarely used */ unsigned int dcache_size; unsigned int dcache_line_size; unsigned int icache_size; diff --git a/include/asm-sparc64/pgalloc.h b/include/asm-sparc64/pgalloc.h index ecea1bbdc1..12e4a273bd 100644 --- a/include/asm-sparc64/pgalloc.h +++ b/include/asm-sparc64/pgalloc.h @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -13,164 +14,59 @@ #include /* Page table allocation/freeing. */ -#ifdef CONFIG_SMP -/* Sliiiicck */ -#define pgt_quicklists local_cpu_data() -#else -extern struct pgtable_cache_struct { - unsigned long *pgd_cache; - unsigned long *pte_cache; - unsigned int pgcache_size; -} pgt_quicklists; -#endif -#define pgd_quicklist (pgt_quicklists.pgd_cache) -#define pte_quicklist (pgt_quicklists.pte_cache) -#define pgtable_cache_size (pgt_quicklists.pgcache_size) +extern kmem_cache_t *pgtable_cache; -static inline void free_pgd_fast(pgd_t *pgd) +static inline pgd_t *pgd_alloc(struct mm_struct *mm) { - preempt_disable(); - *(unsigned long *)pgd = (unsigned long) pgd_quicklist; - pgd_quicklist = (unsigned long *) pgd; - pgtable_cache_size++; - preempt_enable(); + return kmem_cache_alloc(pgtable_cache, GFP_KERNEL); } -static inline pgd_t *get_pgd_fast(void) +static inline void pgd_free(pgd_t *pgd) { - unsigned long *ret; - - preempt_disable(); - if((ret = pgd_quicklist) != NULL) { - pgd_quicklist = (unsigned long *)(*ret); - ret[0] = 0; - pgtable_cache_size--; - preempt_enable(); - } else { - preempt_enable(); - ret = (unsigned long *) __get_free_page(GFP_KERNEL|__GFP_REPEAT); - if(ret) - memset(ret, 0, PAGE_SIZE); - } - return (pgd_t *)ret; -} - -static inline void free_pgd_slow(pgd_t *pgd) -{ - free_page((unsigned long)pgd); + kmem_cache_free(pgtable_cache, pgd); } #define pud_populate(MM, PUD, PMD) pud_set(PUD, PMD) -static inline pmd_t *pmd_alloc_one_fast(void) -{ - unsigned long *ret; - - preempt_disable(); - ret = (unsigned long *) pte_quicklist; - if (likely(ret)) { - pte_quicklist = (unsigned long *)(*ret); - ret[0] = 0; - pgtable_cache_size--; - } - preempt_enable(); - - return (pmd_t *) ret; -} - -static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address) -{ - pmd_t *pmd; - - pmd = pmd_alloc_one_fast(); - if (unlikely(!pmd)) { - pmd = (pmd_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT); - if (pmd) - memset(pmd, 0, PAGE_SIZE); - } - return pmd; -} - -static inline void free_pmd_fast(pmd_t *pmd) -{ - preempt_disable(); - *(unsigned long *)pmd = (unsigned long) pte_quicklist; - pte_quicklist = (unsigned long *) pmd; - pgtable_cache_size++; - preempt_enable(); -} - -static inline void free_pmd_slow(pmd_t *pmd) -{ - free_page((unsigned long)pmd); -} - -#define pmd_populate_kernel(MM, PMD, PTE) pmd_set(PMD, PTE) -#define pmd_populate(MM,PMD,PTE_PAGE) \ - pmd_populate_kernel(MM,PMD,page_address(PTE_PAGE)) - -static inline pte_t *pte_alloc_one_fast(void) +static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr) { - unsigned long *ret; - - preempt_disable(); - ret = (unsigned long *) pte_quicklist; - if (likely(ret)) { - pte_quicklist = (unsigned long *)(*ret); - ret[0] = 0; - pgtable_cache_size--; - } - preempt_enable(); - - return (pte_t *) ret; + return kmem_cache_alloc(pgtable_cache, + GFP_KERNEL|__GFP_REPEAT); } -static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) +static inline void pmd_free(pmd_t *pmd) { - pte_t *ptep = pte_alloc_one_fast(); - - if (likely(ptep)) - return ptep; - - return (pte_t *) get_zeroed_page(GFP_KERNEL|__GFP_REPEAT); + kmem_cache_free(pgtable_cache, pmd); } -static inline struct page *pte_alloc_one(struct mm_struct *mm, unsigned long addr) +static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, + unsigned long address) { - pte_t *pte = pte_alloc_one_fast(); - - if (likely(pte)) - return virt_to_page(pte); - - return alloc_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, 0); + return kmem_cache_alloc(pgtable_cache, + GFP_KERNEL|__GFP_REPEAT); } -static inline void free_pte_fast(pte_t *pte) +static inline struct page *pte_alloc_one(struct mm_struct *mm, + unsigned long address) { - preempt_disable(); - *(unsigned long *)pte = (unsigned long) pte_quicklist; - pte_quicklist = (unsigned long *) pte; - pgtable_cache_size++; - preempt_enable(); + return virt_to_page(pte_alloc_one_kernel(mm, address)); } - -static inline void free_pte_slow(pte_t *pte) -{ - free_page((unsigned long) pte); -} - + static inline void pte_free_kernel(pte_t *pte) { - free_pte_fast(pte); + kmem_cache_free(pgtable_cache, pte); } static inline void pte_free(struct page *ptepage) { - free_pte_fast(page_address(ptepage)); + pte_free_kernel(page_address(ptepage)); } -#define pmd_free(pmd) free_pmd_fast(pmd) -#define pgd_free(pgd) free_pgd_fast(pgd) -#define pgd_alloc(mm) get_pgd_fast() + +#define pmd_populate_kernel(MM, PMD, PTE) pmd_set(PMD, PTE) +#define pmd_populate(MM,PMD,PTE_PAGE) \ + pmd_populate_kernel(MM,PMD,page_address(PTE_PAGE)) + +#define check_pgt_cache() do { } while (0) #endif /* _SPARC64_PGALLOC_H */ diff --git a/include/asm-sparc64/pgtable.h b/include/asm-sparc64/pgtable.h index f3ba1e0581..77ba0b6cc1 100644 --- a/include/asm-sparc64/pgtable.h +++ b/include/asm-sparc64/pgtable.h @@ -432,12 +432,7 @@ extern unsigned long get_fb_unmapped_area(struct file *filp, unsigned long, unsigned long); #define HAVE_ARCH_FB_UNMAPPED_AREA -/* - * No page table caches to initialise - */ -#define pgtable_cache_init() do { } while (0) - -extern void check_pgt_cache(void); +extern void pgtable_cache_init(void); #endif /* !(__ASSEMBLY__) */ -- cgit v1.2.2 From 56fb4df6da76c35dca22036174e2d1edef83ff1f Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 26 Feb 2006 23:24:22 -0800 Subject: [SPARC64]: Elminate all usage of hard-coded trap globals. UltraSPARC has special sets of global registers which are switched to for certain trap types. There is one set for MMU related traps, one set of Interrupt Vector processing, and another set (called the Alternate globals) for all other trap types. For what seems like forever we've hard coded the values in some of these trap registers. Some examples include: 1) Interrupt Vector global %g6 holds current processors interrupt work struct where received interrupts are managed for IRQ handler dispatch. 2) MMU global %g7 holds the base of the page tables of the currently active address space. 3) Alternate global %g6 held the current_thread_info() value. Such hardcoding has resulted in some serious issues in many areas. There are some code sequences where having another register available would help clean up the implementation. Taking traps such as cross-calls from the OBP firmware requires some trick code sequences wherein we have to save away and restore all of the special sets of global registers when we enter/exit OBP. We were also using the IMMU TSB register on SMP to hold the per-cpu area base address, which doesn't work any longer now that we actually use the TSB facility of the cpu. The implementation is pretty straight forward. One tricky bit is getting the current processor ID as that is different on different cpu variants. We use a stub with a fancy calling convention which we patch at boot time. The calling convention is that the stub is branched to and the (PC - 4) to return to is in register %g1. The cpu number is left in %g6. This stub can be invoked by using the __GET_CPUID macro. We use an array of per-cpu trap state to store the current thread and physical address of the current address space's page tables. The TRAP_LOAD_THREAD_REG loads %g6 with the current thread from this table, it uses __GET_CPUID and also clobbers %g1. TRAP_LOAD_IRQ_WORK is used by the interrupt vector processing to load the current processor's IRQ software state into %g6. It also uses __GET_CPUID and clobbers %g1. Finally, TRAP_LOAD_PGD_PHYS loads the physical address base of the current address space's page tables into %g7, it clobbers %g1 and uses __GET_CPUID. Many refinements are possible, as well as some tuning, with this stuff in place. Signed-off-by: David S. Miller --- include/asm-sparc64/cpudata.h | 86 ++++++++++++++++++++++++++++++++++++++++++- include/asm-sparc64/system.h | 2 + include/asm-sparc64/ttable.h | 18 ++++----- 3 files changed, 95 insertions(+), 11 deletions(-) (limited to 'include') diff --git a/include/asm-sparc64/cpudata.h b/include/asm-sparc64/cpudata.h index f7c0faede8..6c57cbb9a7 100644 --- a/include/asm-sparc64/cpudata.h +++ b/include/asm-sparc64/cpudata.h @@ -1,12 +1,15 @@ /* cpudata.h: Per-cpu parameters. * - * Copyright (C) 2003, 2005 David S. Miller (davem@redhat.com) + * Copyright (C) 2003, 2005, 2006 David S. Miller (davem@davemloft.net) */ #ifndef _SPARC64_CPUDATA_H #define _SPARC64_CPUDATA_H +#ifndef __ASSEMBLY__ + #include +#include typedef struct { /* Dcache line 1 */ @@ -32,4 +35,85 @@ DECLARE_PER_CPU(cpuinfo_sparc, __cpu_data); #define cpu_data(__cpu) per_cpu(__cpu_data, (__cpu)) #define local_cpu_data() __get_cpu_var(__cpu_data) +/* Trap handling code needs to get at a few critical values upon + * trap entry and to process TSB misses. These cannot be in the + * per_cpu() area as we really need to lock them into the TLB and + * thus make them part of the main kernel image. As a result we + * try to make this as small as possible. + * + * This is padded out and aligned to 64-bytes to avoid false sharing + * on SMP. + */ + +/* If you modify the size of this structure, please update + * TRAP_BLOCK_SZ_SHIFT below. + */ +struct thread_info; +struct trap_per_cpu { +/* D-cache line 1 */ + struct thread_info *thread; + unsigned long pgd_paddr; + unsigned long __pad1[2]; + +/* D-cache line 2 */ + unsigned long __pad2[4]; +} __attribute__((aligned(64))); +extern struct trap_per_cpu trap_block[NR_CPUS]; +extern void init_cur_cpu_trap(void); +extern void per_cpu_patch(void); + +#endif /* !(__ASSEMBLY__) */ + +#define TRAP_PER_CPU_THREAD 0x00 +#define TRAP_PER_CPU_PGD_PADDR 0x08 + +#define TRAP_BLOCK_SZ_SHIFT 6 + +/* Clobbers %g1, loads %g6 with local processor's cpuid */ +#define __GET_CPUID \ + ba,pt %xcc, __get_cpu_id; \ + rd %pc, %g1; + +/* Clobbers %g1, current address space PGD phys address into %g7. */ +#define TRAP_LOAD_PGD_PHYS \ + __GET_CPUID \ + sllx %g6, TRAP_BLOCK_SZ_SHIFT, %g6; \ + sethi %hi(trap_block), %g7; \ + or %g7, %lo(trap_block), %g7; \ + add %g7, %g6, %g7; \ + ldx [%g7 + TRAP_PER_CPU_PGD_PADDR], %g7; + +/* Clobbers %g1, loads local processor's IRQ work area into %g6. */ +#define TRAP_LOAD_IRQ_WORK \ + __GET_CPUID \ + sethi %hi(__irq_work), %g1; \ + sllx %g6, 6, %g6; \ + or %g1, %lo(__irq_work), %g1; \ + add %g1, %g6, %g6; + +/* Clobbers %g1, loads %g6 with current thread info pointer. */ +#define TRAP_LOAD_THREAD_REG \ + __GET_CPUID \ + sllx %g6, TRAP_BLOCK_SZ_SHIFT, %g6; \ + sethi %hi(trap_block), %g1; \ + or %g1, %lo(trap_block), %g1; \ + ldx [%g1 + %g6], %g6; + +/* Given the current thread info pointer in %g6, load the per-cpu + * area base of the current processor into %g5. REG1 and REG2 are + * clobbered. + */ +#ifdef CONFIG_SMP +#define LOAD_PER_CPU_BASE(REG1, REG2) \ + ldub [%g6 + TI_CPU], REG1; \ + sethi %hi(__per_cpu_shift), %g5; \ + sethi %hi(__per_cpu_base), REG2; \ + ldx [%g5 + %lo(__per_cpu_shift)], %g5; \ + ldx [REG2 + %lo(__per_cpu_base)], REG2; \ + sllx REG1, %g5, %g5; \ + add %g5, REG2, %g5; +#else +#define LOAD_PER_CPU_BASE(REG1, REG2) +#endif + #endif /* _SPARC64_CPUDATA_H */ diff --git a/include/asm-sparc64/system.h b/include/asm-sparc64/system.h index af254e5818..26c0807af3 100644 --- a/include/asm-sparc64/system.h +++ b/include/asm-sparc64/system.h @@ -209,6 +209,8 @@ do { if (test_thread_flag(TIF_PERFCTR)) { \ /* so that ASI is only written if it changes, think again. */ \ __asm__ __volatile__("wr %%g0, %0, %%asi" \ : : "r" (__thread_flag_byte_ptr(task_thread_info(next))[TI_FLAG_BYTE_CURRENT_DS]));\ + trap_block[current_thread_info()->cpu].thread = \ + task_thread_info(next); \ __asm__ __volatile__( \ "mov %%g4, %%g7\n\t" \ "wrpr %%g0, 0x95, %%pstate\n\t" \ diff --git a/include/asm-sparc64/ttable.h b/include/asm-sparc64/ttable.h index 2784f80094..f557db4faf 100644 --- a/include/asm-sparc64/ttable.h +++ b/include/asm-sparc64/ttable.h @@ -109,14 +109,14 @@ nop;nop;nop; #define TRAP_UTRAP(handler,lvl) \ - ldx [%g6 + TI_UTRAPS], %g1; \ - sethi %hi(109f), %g7; \ - brz,pn %g1, utrap; \ - or %g7, %lo(109f), %g7; \ - ba,pt %xcc, utrap; \ -109: ldx [%g1 + handler*8], %g1; \ - ba,pt %xcc, utrap_ill; \ - mov lvl, %o1; + mov handler, %g3; \ + ba,pt %xcc, utrap_trap; \ + mov lvl, %g4; \ + nop; \ + nop; \ + nop; \ + nop; \ + nop; #ifdef CONFIG_SUNOS_EMUL #define SUNOS_SYSCALL_TRAP SYSCALL_TRAP(linux_sparc_syscall32, sunos_sys_table) @@ -136,8 +136,6 @@ #else #define SOLARIS_SYSCALL_TRAP TRAP(solaris_syscall) #endif -/* FIXME: Write these actually */ -#define NETBSD_SYSCALL_TRAP TRAP(netbsd_syscall) #define BREAKPOINT_TRAP TRAP(breakpoint_trap) #define TRAP_IRQ(routine, level) \ -- cgit v1.2.2 From 09f94287f7260e03bbeab497e743691fafcc22c3 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 31 Jan 2006 18:31:06 -0800 Subject: [SPARC64]: TSB refinements. Move {init_new,destroy}_context() out of line. Do not put huge pages into the TSB, only base page size translations. There are some clever things we could do here, but for now let's be correct instead of fancy. Signed-off-by: David S. Miller --- include/asm-sparc64/mmu_context.h | 32 ++------------------------------ include/asm-sparc64/pgtable.h | 4 ++++ 2 files changed, 6 insertions(+), 30 deletions(-) (limited to 'include') diff --git a/include/asm-sparc64/mmu_context.h b/include/asm-sparc64/mmu_context.h index 34640a370a..0dffb4ce8a 100644 --- a/include/asm-sparc64/mmu_context.h +++ b/include/asm-sparc64/mmu_context.h @@ -19,36 +19,8 @@ extern unsigned long tlb_context_cache; extern unsigned long mmu_context_bmap[]; extern void get_new_mmu_context(struct mm_struct *mm); - -/* Initialize a new mmu context. This is invoked when a new - * address space instance (unique or shared) is instantiated. - * This just needs to set mm->context to an invalid context. - */ -#define init_new_context(__tsk, __mm) \ -({ unsigned long __pg = get_zeroed_page(GFP_KERNEL); \ - (__mm)->context.sparc64_ctx_val = 0UL; \ - (__mm)->context.sparc64_tsb = \ - (unsigned long *) __pg; \ - (__pg ? 0 : -ENOMEM); \ -}) - - -/* Destroy a dead context. This occurs when mmput drops the - * mm_users count to zero, the mmaps have been released, and - * all the page tables have been flushed. Our job is to destroy - * any remaining processor-specific state, and in the sparc64 - * case this just means freeing up the mmu context ID held by - * this task if valid. - */ -#define destroy_context(__mm) \ -do { free_page((unsigned long)(__mm)->context.sparc64_tsb); \ - spin_lock(&ctx_alloc_lock); \ - if (CTX_VALID((__mm)->context)) { \ - unsigned long nr = CTX_NRBITS((__mm)->context); \ - mmu_context_bmap[nr>>6] &= ~(1UL << (nr & 63)); \ - } \ - spin_unlock(&ctx_alloc_lock); \ -} while(0) +extern int init_new_context(struct task_struct *tsk, struct mm_struct *mm); +extern void destroy_context(struct mm_struct *mm); extern unsigned long tsb_context_switch(unsigned long pgd_pa, unsigned long *tsb); diff --git a/include/asm-sparc64/pgtable.h b/include/asm-sparc64/pgtable.h index 77ba0b6cc1..2b2ecd6104 100644 --- a/include/asm-sparc64/pgtable.h +++ b/include/asm-sparc64/pgtable.h @@ -116,6 +116,10 @@ #define _PAGE_W _AC(0x0000000000000002,UL) /* Writable */ #define _PAGE_G _AC(0x0000000000000001,UL) /* Global */ +#define _PAGE_ALL_SZ_BITS \ + (_PAGE_SZ4MB | _PAGE_SZ512K | _PAGE_SZ64K | \ + _PAGE_SZ8K | _PAGE_SZ32MB | _PAGE_SZ256MB) + /* Here are the SpitFire software bits we use in the TTE's. * * WARNING: If you are going to try and start using some -- cgit v1.2.2 From 98c5584cfc47932c4f3ccf5eee2e0bae1447b85e Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 31 Jan 2006 18:31:20 -0800 Subject: [SPARC64]: Add infrastructure for dynamic TSB sizing. This also cleans up tsb_context_switch(). The assembler routine is now __tsb_context_switch() and the former is an inline function that picks out the bits from the mm_struct and passes it into the assembler code as arguments. setup_tsb_parms() computes the locked TLB entry to map the TSB. Later when we support using the physical address quad load instructions of Cheetah+ and later, we'll simply use the physical address for the TSB register value and set the map virtual and PTE both to zero. Signed-off-by: David S. Miller --- include/asm-sparc64/mmu.h | 13 ++++++++++++- include/asm-sparc64/mmu_context.h | 15 +++++++++++---- include/asm-sparc64/tsb.h | 2 +- 3 files changed, 24 insertions(+), 6 deletions(-) (limited to 'include') diff --git a/include/asm-sparc64/mmu.h b/include/asm-sparc64/mmu.h index 36384cf7fa..2effeba247 100644 --- a/include/asm-sparc64/mmu.h +++ b/include/asm-sparc64/mmu.h @@ -90,9 +90,20 @@ #ifndef __ASSEMBLY__ +#define TSB_ENTRY_ALIGNMENT 16 + +struct tsb { + unsigned long tag; + unsigned long pte; +} __attribute__((aligned(TSB_ENTRY_ALIGNMENT))); + typedef struct { unsigned long sparc64_ctx_val; - unsigned long *sparc64_tsb; + struct tsb *tsb; + unsigned long tsb_nentries; + unsigned long tsb_reg_val; + unsigned long tsb_map_vaddr; + unsigned long tsb_map_pte; } mm_context_t; #endif /* !__ASSEMBLY__ */ diff --git a/include/asm-sparc64/mmu_context.h b/include/asm-sparc64/mmu_context.h index 0dffb4ce8a..0a950f151d 100644 --- a/include/asm-sparc64/mmu_context.h +++ b/include/asm-sparc64/mmu_context.h @@ -22,7 +22,15 @@ extern void get_new_mmu_context(struct mm_struct *mm); extern int init_new_context(struct task_struct *tsk, struct mm_struct *mm); extern void destroy_context(struct mm_struct *mm); -extern unsigned long tsb_context_switch(unsigned long pgd_pa, unsigned long *tsb); +extern void __tsb_context_switch(unsigned long pgd_pa, unsigned long tsb_reg, + unsigned long tsb_vaddr, unsigned long tsb_pte); + +static inline void tsb_context_switch(struct mm_struct *mm) +{ + __tsb_context_switch(__pa(mm->pgd), mm->context.tsb_reg_val, + mm->context.tsb_map_vaddr, + mm->context.tsb_map_pte); +} /* Set MMU context in the actual hardware. */ #define load_secondary_context(__mm) \ @@ -52,8 +60,7 @@ static inline void switch_mm(struct mm_struct *old_mm, struct mm_struct *mm, str if (!ctx_valid || (old_mm != mm)) { load_secondary_context(mm); - tsb_context_switch(__pa(mm->pgd), - mm->context.sparc64_tsb); + tsb_context_switch(mm); } /* Even if (mm == old_mm) we _must_ check @@ -91,7 +98,7 @@ static inline void activate_mm(struct mm_struct *active_mm, struct mm_struct *mm load_secondary_context(mm); __flush_tlb_mm(CTX_HWBITS(mm->context), SECONDARY_CONTEXT); - tsb_context_switch(__pa(mm->pgd), mm->context.sparc64_tsb); + tsb_context_switch(mm); } #endif /* !(__ASSEMBLY__) */ diff --git a/include/asm-sparc64/tsb.h b/include/asm-sparc64/tsb.h index 03d272e0e4..1f93b7d8cd 100644 --- a/include/asm-sparc64/tsb.h +++ b/include/asm-sparc64/tsb.h @@ -19,7 +19,7 @@ * stxa %g5, [%g0] ASI_{D,I}TLB_DATA_IN * retry * - + * * Each 16-byte slot of the TSB is the 8-byte tag and then the 8-byte * PTE. The TAG is of the same layout as the TLB TAG TARGET mmu * register which is: -- cgit v1.2.2 From bd40791e1d289d807b8580abe1f117e9c62894e4 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 31 Jan 2006 18:31:38 -0800 Subject: [SPARC64]: Dynamically grow TSB in response to RSS growth. As the RSS grows, grow the TSB in order to reduce the likelyhood of hash collisions and thus poor hit rates in the TSB. This definitely needs some serious tuning. Signed-off-by: David S. Miller --- include/asm-sparc64/mmu.h | 1 + include/asm-sparc64/mmu_context.h | 7 +++++++ 2 files changed, 8 insertions(+) (limited to 'include') diff --git a/include/asm-sparc64/mmu.h b/include/asm-sparc64/mmu.h index 2effeba247..76008ff6a9 100644 --- a/include/asm-sparc64/mmu.h +++ b/include/asm-sparc64/mmu.h @@ -100,6 +100,7 @@ struct tsb { typedef struct { unsigned long sparc64_ctx_val; struct tsb *tsb; + unsigned long tsb_rss_limit; unsigned long tsb_nentries; unsigned long tsb_reg_val; unsigned long tsb_map_vaddr; diff --git a/include/asm-sparc64/mmu_context.h b/include/asm-sparc64/mmu_context.h index 0a950f151d..1d23267882 100644 --- a/include/asm-sparc64/mmu_context.h +++ b/include/asm-sparc64/mmu_context.h @@ -32,6 +32,13 @@ static inline void tsb_context_switch(struct mm_struct *mm) mm->context.tsb_map_pte); } +extern void tsb_grow(struct mm_struct *mm, unsigned long mm_rss, gfp_t gfp_flags); +#ifdef CONFIG_SMP +extern void smp_tsb_sync(struct mm_struct *mm); +#else +#define smp_tsb_sync(__mm) do { } while (0) +#endif + /* Set MMU context in the actual hardware. */ #define load_secondary_context(__mm) \ __asm__ __volatile__("stxa %0, [%1] %2\n\t" \ -- cgit v1.2.2 From b70c0fa1613c4f69b4a340a0e2bee387560ebbb1 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 31 Jan 2006 18:32:04 -0800 Subject: [SPARC64]: Preload TSB entries from update_mmu_cache(). Signed-off-by: David S. Miller --- include/asm-sparc64/mmu.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/asm-sparc64/mmu.h b/include/asm-sparc64/mmu.h index 76008ff6a9..18f98edfbc 100644 --- a/include/asm-sparc64/mmu.h +++ b/include/asm-sparc64/mmu.h @@ -97,6 +97,8 @@ struct tsb { unsigned long pte; } __attribute__((aligned(TSB_ENTRY_ALIGNMENT))); +extern void tsb_insert(struct tsb *ent, unsigned long tag, unsigned long pte); + typedef struct { unsigned long sparc64_ctx_val; struct tsb *tsb; -- cgit v1.2.2 From 4753eb2ac7022b999e5e484f1a5dc001dba22bd3 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 31 Jan 2006 18:32:44 -0800 Subject: [SPARC64]: Fix incorrect TSB lock bit handling. The TSB_LOCK_BIT define is actually a special value shifted down by 32-bits for the assembler code macros. In C code, this isn't what we want. Signed-off-by: David S. Miller --- include/asm-sparc64/tsb.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/asm-sparc64/tsb.h b/include/asm-sparc64/tsb.h index 1f93b7d8cd..09ab3aaa8d 100644 --- a/include/asm-sparc64/tsb.h +++ b/include/asm-sparc64/tsb.h @@ -47,13 +47,14 @@ * possible solution is to use RCU for the freeing of the TSB. */ -#define TSB_TAG_LOCK (1 << (47 - 32)) +#define TSB_TAG_LOCK_BIT 47 +#define TSB_TAG_LOCK_HIGH (1 << (TSB_TAG_LOCK_BIT - 32)) #define TSB_MEMBAR membar #StoreStore #define TSB_LOCK_TAG(TSB, REG1, REG2) \ 99: lduwa [TSB] ASI_N, REG1; \ - sethi %hi(TSB_TAG_LOCK), REG2;\ + sethi %hi(TSB_TAG_LOCK_HIGH), REG2;\ andcc REG1, REG2, %g0; \ bne,pn %icc, 99b; \ nop; \ -- cgit v1.2.2 From a8b900d801697609d1b56cc9c110148c64678068 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 31 Jan 2006 18:33:37 -0800 Subject: [SPARC64]: Kill sole argument passed to setup_tba(). No longer used, and move extern declaration to a header file. Signed-off-by: David S. Miller --- include/asm-sparc64/cpudata.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/asm-sparc64/cpudata.h b/include/asm-sparc64/cpudata.h index 6c57cbb9a7..16d6289138 100644 --- a/include/asm-sparc64/cpudata.h +++ b/include/asm-sparc64/cpudata.h @@ -61,6 +61,7 @@ struct trap_per_cpu { extern struct trap_per_cpu trap_block[NR_CPUS]; extern void init_cur_cpu_trap(void); extern void per_cpu_patch(void); +extern void setup_tba(void); #endif /* !(__ASSEMBLY__) */ -- cgit v1.2.2 From 2f7ee7c63f08b7f883b710a29d91c1891b81b8e1 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 31 Jan 2006 18:33:49 -0800 Subject: [SPARC64]: Increase swapper_tsb size to 32K. Signed-off-by: David S. Miller --- include/asm-sparc64/tsb.h | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/asm-sparc64/tsb.h b/include/asm-sparc64/tsb.h index 09ab3aaa8d..1addd91d72 100644 --- a/include/asm-sparc64/tsb.h +++ b/include/asm-sparc64/tsb.h @@ -143,6 +143,14 @@ add REG1, (3 * 8), REG1; \ 99: + /* We use a 32K TSB for the whole kernel, this allows to + * handle about 16MB of modules and vmalloc mappings without + * incurring many hash conflicts. + */ +#define KERNEL_TSB_SIZE_BYTES (32 * 1024) +#define KERNEL_TSB_NENTRIES \ + (KERNEL_TSB_SIZE_BYTES / 16) + /* Do a kernel TSB lookup at tl>0 on VADDR+TAG, branch to OK_LABEL * on TSB hit. REG1, REG2, REG3, and REG4 are used as temporaries * and the found TTE will be left in REG1. REG3 and REG4 must @@ -150,12 +158,11 @@ * * VADDR and TAG will be preserved and not clobbered by this macro. */ - /* XXX non-8K base page size support... */ #define KERN_TSB_LOOKUP_TL1(VADDR, TAG, REG1, REG2, REG3, REG4, OK_LABEL) \ sethi %hi(swapper_tsb), REG1; \ or REG1, %lo(swapper_tsb), REG1; \ - srlx VADDR, 13, REG2; \ - and REG2, (512 - 1), REG2; \ + srlx VADDR, PAGE_SHIFT, REG2; \ + and REG2, (KERNEL_TSB_NENTRIES - 1), REG2; \ sllx REG2, 4, REG2; \ add REG1, REG2, REG2; \ ldda [REG2] ASI_NUCLEUS_QUAD_LDD, REG3; \ -- cgit v1.2.2 From 86b818687d4894063ecd1190e54717a0cce8c009 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 31 Jan 2006 18:34:51 -0800 Subject: [SPARC64]: Fix race in LOAD_PER_CPU_BASE() Since we use %g5 itself as a temporary, it can get clobbered if we take an interrupt mid-stream and thus cause end up with the final %g5 value too early as a result of rtrap processing. Set %g5 at the very end, atomically, to avoid this problem. Signed-off-by: David S. Miller --- include/asm-sparc64/cpudata.h | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) (limited to 'include') diff --git a/include/asm-sparc64/cpudata.h b/include/asm-sparc64/cpudata.h index 16d6289138..f83768883e 100644 --- a/include/asm-sparc64/cpudata.h +++ b/include/asm-sparc64/cpudata.h @@ -101,20 +101,25 @@ extern void setup_tba(void); ldx [%g1 + %g6], %g6; /* Given the current thread info pointer in %g6, load the per-cpu - * area base of the current processor into %g5. REG1 and REG2 are + * area base of the current processor into %g5. REG1, REG2, and REG3 are * clobbered. + * + * You absolutely cannot use %g5 as a temporary in this code. The + * reason is that traps can happen during execution, and return from + * trap will load the fully resolved %g5 per-cpu base. This can corrupt + * the calculations done by the macro mid-stream. */ #ifdef CONFIG_SMP -#define LOAD_PER_CPU_BASE(REG1, REG2) \ +#define LOAD_PER_CPU_BASE(REG1, REG2, REG3) \ ldub [%g6 + TI_CPU], REG1; \ - sethi %hi(__per_cpu_shift), %g5; \ + sethi %hi(__per_cpu_shift), REG3; \ sethi %hi(__per_cpu_base), REG2; \ - ldx [%g5 + %lo(__per_cpu_shift)], %g5; \ + ldx [REG3 + %lo(__per_cpu_shift)], REG3; \ ldx [REG2 + %lo(__per_cpu_base)], REG2; \ - sllx REG1, %g5, %g5; \ - add %g5, REG2, %g5; + sllx REG1, REG3, REG3; \ + add REG3, REG2, %g5; #else -#define LOAD_PER_CPU_BASE(REG1, REG2) +#define LOAD_PER_CPU_BASE(REG1, REG2, REG3) #endif #endif /* _SPARC64_CPUDATA_H */ -- cgit v1.2.2 From b0fd4e49aea8a460afab7bc67cd618e2d19291d4 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 31 Jan 2006 23:13:29 -0800 Subject: [SPARC64]: Kill out-of-date commentary in asm-sparc64/tsb.h Signed-off-by: David S. Miller --- include/asm-sparc64/tsb.h | 8 -------- 1 file changed, 8 deletions(-) (limited to 'include') diff --git a/include/asm-sparc64/tsb.h b/include/asm-sparc64/tsb.h index 1addd91d72..f384565212 100644 --- a/include/asm-sparc64/tsb.h +++ b/include/asm-sparc64/tsb.h @@ -37,14 +37,6 @@ * choose to use bit 47 in the tag. Also, since we never map anything * at page zero in context zero, we use zero as an invalid tag entry. * When the lock bit is set, this forces a tag comparison failure. - * - * Currently, we allocate an 8K TSB per-process and we use it for both - * I-TLB and D-TLB misses. Perhaps at some point we'll add code that - * monitors the number of active pages in the process as we get - * major/minor faults, and grow the TSB in response. The only trick - * in implementing that is synchronizing the freeing of the old TSB - * wrt. parallel TSB updates occuring on other processors. On - * possible solution is to use RCU for the freeing of the TSB. */ #define TSB_TAG_LOCK_BIT 47 -- cgit v1.2.2 From 517af33237ecfc3c8a93b335365fa61e741ceca4 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 1 Feb 2006 15:55:21 -0800 Subject: [SPARC64]: Access TSB with physical addresses when possible. This way we don't need to lock the TSB into the TLB. The trick is that every TSB load/store is registered into a special instruction patch section. The default uses virtual addresses, and the patch instructions use physical address load/stores. We can't do this on all chips because only cheetah+ and later have the physical variant of the atomic quad load. Signed-off-by: David S. Miller --- include/asm-sparc64/mmu.h | 3 +- include/asm-sparc64/tsb.h | 94 ++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 91 insertions(+), 6 deletions(-) (limited to 'include') diff --git a/include/asm-sparc64/mmu.h b/include/asm-sparc64/mmu.h index 18f98edfbc..55e622711b 100644 --- a/include/asm-sparc64/mmu.h +++ b/include/asm-sparc64/mmu.h @@ -97,7 +97,8 @@ struct tsb { unsigned long pte; } __attribute__((aligned(TSB_ENTRY_ALIGNMENT))); -extern void tsb_insert(struct tsb *ent, unsigned long tag, unsigned long pte); +extern void __tsb_insert(unsigned long ent, unsigned long tag, unsigned long pte); +extern void tsb_flush(unsigned long ent, unsigned long tag); typedef struct { unsigned long sparc64_ctx_val; diff --git a/include/asm-sparc64/tsb.h b/include/asm-sparc64/tsb.h index f384565212..44709cde56 100644 --- a/include/asm-sparc64/tsb.h +++ b/include/asm-sparc64/tsb.h @@ -44,7 +44,89 @@ #define TSB_MEMBAR membar #StoreStore +/* Some cpus support physical address quad loads. We want to use + * those if possible so we don't need to hard-lock the TSB mapping + * into the TLB. We encode some instruction patching in order to + * support this. + * + * The kernel TSB is locked into the TLB by virtue of being in the + * kernel image, so we don't play these games for swapper_tsb access. + */ +#ifndef __ASSEMBLY__ +struct tsb_phys_patch_entry { + unsigned int addr; + unsigned int insn; +}; +extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end; +#endif +#define TSB_LOAD_QUAD(TSB, REG) \ +661: ldda [TSB] ASI_NUCLEUS_QUAD_LDD, REG; \ + .section .tsb_phys_patch, "ax"; \ + .word 661b; \ + ldda [TSB] ASI_QUAD_LDD_PHYS, REG; \ + .previous + +#define TSB_LOAD_TAG_HIGH(TSB, REG) \ +661: lduwa [TSB] ASI_N, REG; \ + .section .tsb_phys_patch, "ax"; \ + .word 661b; \ + lduwa [TSB] ASI_PHYS_USE_EC, REG; \ + .previous + +#define TSB_LOAD_TAG(TSB, REG) \ +661: ldxa [TSB] ASI_N, REG; \ + .section .tsb_phys_patch, "ax"; \ + .word 661b; \ + ldxa [TSB] ASI_PHYS_USE_EC, REG; \ + .previous + +#define TSB_CAS_TAG_HIGH(TSB, REG1, REG2) \ +661: casa [TSB] ASI_N, REG1, REG2; \ + .section .tsb_phys_patch, "ax"; \ + .word 661b; \ + casa [TSB] ASI_PHYS_USE_EC, REG1, REG2; \ + .previous + +#define TSB_CAS_TAG(TSB, REG1, REG2) \ +661: casxa [TSB] ASI_N, REG1, REG2; \ + .section .tsb_phys_patch, "ax"; \ + .word 661b; \ + casxa [TSB] ASI_PHYS_USE_EC, REG1, REG2; \ + .previous + +#define TSB_STORE(ADDR, VAL) \ +661: stxa VAL, [ADDR] ASI_N; \ + .section .tsb_phys_patch, "ax"; \ + .word 661b; \ + stxa VAL, [ADDR] ASI_PHYS_USE_EC; \ + .previous + #define TSB_LOCK_TAG(TSB, REG1, REG2) \ +99: TSB_LOAD_TAG_HIGH(TSB, REG1); \ + sethi %hi(TSB_TAG_LOCK_HIGH), REG2;\ + andcc REG1, REG2, %g0; \ + bne,pn %icc, 99b; \ + nop; \ + TSB_CAS_TAG_HIGH(TSB, REG1, REG2); \ + cmp REG1, REG2; \ + bne,pn %icc, 99b; \ + nop; \ + TSB_MEMBAR + +#define TSB_WRITE(TSB, TTE, TAG) \ + add TSB, 0x8, TSB; \ + TSB_STORE(TSB, TTE); \ + sub TSB, 0x8, TSB; \ + TSB_MEMBAR; \ + TSB_STORE(TSB, TAG); + +#define KTSB_LOAD_QUAD(TSB, REG) \ + ldda [TSB] ASI_NUCLEUS_QUAD_LDD, REG; + +#define KTSB_STORE(ADDR, VAL) \ + stxa VAL, [ADDR] ASI_N; + +#define KTSB_LOCK_TAG(TSB, REG1, REG2) \ 99: lduwa [TSB] ASI_N, REG1; \ sethi %hi(TSB_TAG_LOCK_HIGH), REG2;\ andcc REG1, REG2, %g0; \ @@ -56,10 +138,12 @@ nop; \ TSB_MEMBAR -#define TSB_WRITE(TSB, TTE, TAG) \ - stx TTE, [TSB + 0x08]; \ - TSB_MEMBAR; \ - stx TAG, [TSB + 0x00]; +#define KTSB_WRITE(TSB, TTE, TAG) \ + add TSB, 0x8, TSB; \ + stxa TTE, [TSB] ASI_N; \ + sub TSB, 0x8, TSB; \ + TSB_MEMBAR; \ + stxa TAG, [TSB] ASI_N; /* Do a kernel page table walk. Leaves physical PTE pointer in * REG1. Jumps to FAIL_LABEL on early page table walk termination. @@ -157,7 +241,7 @@ and REG2, (KERNEL_TSB_NENTRIES - 1), REG2; \ sllx REG2, 4, REG2; \ add REG1, REG2, REG2; \ - ldda [REG2] ASI_NUCLEUS_QUAD_LDD, REG3; \ + KTSB_LOAD_QUAD(REG2, REG3); \ cmp REG3, TAG; \ be,a,pt %xcc, OK_LABEL; \ mov REG4, REG1; -- cgit v1.2.2 From 7bec08e38a7d0f088994f6eec9b6374652ea71fb Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 2 Feb 2006 01:20:18 -0800 Subject: [SPARC64]: Correctable ECC errors cannot occur at trap level > 0. The are distrupting, which by the sparc v9 definition means they can only occur when interrupts are enabled in the %pstate register. This never occurs in any of the trap handling code running at trap levels > 0. So just mark it as an unexpected trap. This allows us to kill off the cee_stuff member of struct thread_info. Signed-off-by: David S. Miller --- include/asm-sparc64/thread_info.h | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'include') diff --git a/include/asm-sparc64/thread_info.h b/include/asm-sparc64/thread_info.h index ac9d068aab..2ebf7f27bf 100644 --- a/include/asm-sparc64/thread_info.h +++ b/include/asm-sparc64/thread_info.h @@ -64,8 +64,6 @@ struct thread_info { __u64 kernel_cntd0, kernel_cntd1; __u64 pcr_reg; - __u64 cee_stuff; - struct restart_block restart_block; struct pt_regs *kern_una_regs; @@ -104,10 +102,9 @@ struct thread_info { #define TI_KERN_CNTD0 0x00000480 #define TI_KERN_CNTD1 0x00000488 #define TI_PCR 0x00000490 -#define TI_CEE_STUFF 0x00000498 -#define TI_RESTART_BLOCK 0x000004a0 -#define TI_KUNA_REGS 0x000004c8 -#define TI_KUNA_INSN 0x000004d0 +#define TI_RESTART_BLOCK 0x00000498 +#define TI_KUNA_REGS 0x000004c0 +#define TI_KUNA_INSN 0x000004c8 #define TI_FPREGS 0x00000500 /* We embed this in the uppermost byte of thread_info->flags */ -- cgit v1.2.2 From 92704a1c63c3b481870d02636d0b5a70c7e21cd1 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 26 Feb 2006 23:27:19 -0800 Subject: [SPARC64]: Refine code sequences to get the cpu id. On uniprocessor, it's always zero for optimize that. On SMP, the jmpl to the stub kills the return address stack in the cpu branch prediction logic, so expand the code sequence inline and use a code patching section to fix things up. This also always better and explicit register selection, which will be taken advantage of in a future changeset. The hard_smp_processor_id() function is big, so do not inline it. Fix up tests for Jalapeno to also test for Serrano chips too. These tests want "jbus Ultra-IIIi" cases to match, so that is what we should test for. Signed-off-by: David S. Miller --- include/asm-sparc64/cpudata.h | 89 +++++++++++++++++++++++++++++++++---------- include/asm-sparc64/head.h | 1 + include/asm-sparc64/smp.h | 28 +------------- 3 files changed, 71 insertions(+), 47 deletions(-) (limited to 'include') diff --git a/include/asm-sparc64/cpudata.h b/include/asm-sparc64/cpudata.h index f83768883e..da54b4f354 100644 --- a/include/asm-sparc64/cpudata.h +++ b/include/asm-sparc64/cpudata.h @@ -60,9 +60,18 @@ struct trap_per_cpu { } __attribute__((aligned(64))); extern struct trap_per_cpu trap_block[NR_CPUS]; extern void init_cur_cpu_trap(void); -extern void per_cpu_patch(void); extern void setup_tba(void); +#ifdef CONFIG_SMP +struct cpuid_patch_entry { + unsigned int addr; + unsigned int cheetah_safari[4]; + unsigned int cheetah_jbus[4]; + unsigned int starfire[4]; +}; +extern struct cpuid_patch_entry __cpuid_patch, __cpuid_patch_end; +#endif + #endif /* !(__ASSEMBLY__) */ #define TRAP_PER_CPU_THREAD 0x00 @@ -70,35 +79,58 @@ extern void setup_tba(void); #define TRAP_BLOCK_SZ_SHIFT 6 -/* Clobbers %g1, loads %g6 with local processor's cpuid */ -#define __GET_CPUID \ - ba,pt %xcc, __get_cpu_id; \ - rd %pc, %g1; +#ifdef CONFIG_SMP + +#define __GET_CPUID(REG) \ + /* Spitfire implementation (default). */ \ +661: ldxa [%g0] ASI_UPA_CONFIG, REG; \ + srlx REG, 17, REG; \ + and REG, 0x1f, REG; \ + nop; \ + .section .cpuid_patch, "ax"; \ + /* Instruction location. */ \ + .word 661b; \ + /* Cheetah Safari implementation. */ \ + ldxa [%g0] ASI_SAFARI_CONFIG, REG; \ + srlx REG, 17, REG; \ + and REG, 0x3ff, REG; \ + nop; \ + /* Cheetah JBUS implementation. */ \ + ldxa [%g0] ASI_JBUS_CONFIG, REG; \ + srlx REG, 17, REG; \ + and REG, 0x1f, REG; \ + nop; \ + /* Starfire implementation. */ \ + sethi %hi(0x1fff40000d0 >> 9), REG; \ + sllx REG, 9, REG; \ + or REG, 0xd0, REG; \ + lduwa [REG] ASI_PHYS_BYPASS_EC_E, REG;\ + .previous; /* Clobbers %g1, current address space PGD phys address into %g7. */ #define TRAP_LOAD_PGD_PHYS \ - __GET_CPUID \ - sllx %g6, TRAP_BLOCK_SZ_SHIFT, %g6; \ + __GET_CPUID(%g1) \ sethi %hi(trap_block), %g7; \ + sllx %g1, TRAP_BLOCK_SZ_SHIFT, %g1; \ or %g7, %lo(trap_block), %g7; \ - add %g7, %g6, %g7; \ + add %g7, %g1, %g7; \ ldx [%g7 + TRAP_PER_CPU_PGD_PADDR], %g7; /* Clobbers %g1, loads local processor's IRQ work area into %g6. */ #define TRAP_LOAD_IRQ_WORK \ - __GET_CPUID \ - sethi %hi(__irq_work), %g1; \ - sllx %g6, 6, %g6; \ - or %g1, %lo(__irq_work), %g1; \ - add %g1, %g6, %g6; + __GET_CPUID(%g1) \ + sethi %hi(__irq_work), %g6; \ + sllx %g1, 6, %g1; \ + or %g6, %lo(__irq_work), %g6; \ + add %g6, %g1, %g6; /* Clobbers %g1, loads %g6 with current thread info pointer. */ #define TRAP_LOAD_THREAD_REG \ - __GET_CPUID \ - sllx %g6, TRAP_BLOCK_SZ_SHIFT, %g6; \ - sethi %hi(trap_block), %g1; \ - or %g1, %lo(trap_block), %g1; \ - ldx [%g1 + %g6], %g6; + __GET_CPUID(%g1) \ + sethi %hi(trap_block), %g6; \ + sllx %g1, TRAP_BLOCK_SZ_SHIFT, %g1; \ + or %g6, %lo(trap_block), %g6; \ + ldx [%g6 + %g1], %g6; /* Given the current thread info pointer in %g6, load the per-cpu * area base of the current processor into %g5. REG1, REG2, and REG3 are @@ -109,7 +141,6 @@ extern void setup_tba(void); * trap will load the fully resolved %g5 per-cpu base. This can corrupt * the calculations done by the macro mid-stream. */ -#ifdef CONFIG_SMP #define LOAD_PER_CPU_BASE(REG1, REG2, REG3) \ ldub [%g6 + TI_CPU], REG1; \ sethi %hi(__per_cpu_shift), REG3; \ @@ -118,8 +149,26 @@ extern void setup_tba(void); ldx [REG2 + %lo(__per_cpu_base)], REG2; \ sllx REG1, REG3, REG3; \ add REG3, REG2, %g5; + #else + +/* Uniprocessor versions, we know the cpuid is zero. */ +#define TRAP_LOAD_PGD_PHYS \ + sethi %hi(trap_block), %g7; \ + or %g7, %lo(trap_block), %g7; \ + ldx [%g7 + TRAP_PER_CPU_PGD_PADDR], %g7; + +#define TRAP_LOAD_IRQ_WORK \ + sethi %hi(__irq_work), %g6; \ + or %g6, %lo(__irq_work), %g6; + +#define TRAP_LOAD_THREAD_REG \ + sethi %hi(trap_block), %g6; \ + ldx [%g6 + %lo(trap_block)], %g6; + +/* No per-cpu areas on uniprocessor, so no need to load %g5. */ #define LOAD_PER_CPU_BASE(REG1, REG2, REG3) -#endif + +#endif /* !(CONFIG_SMP) */ #endif /* _SPARC64_CPUDATA_H */ diff --git a/include/asm-sparc64/head.h b/include/asm-sparc64/head.h index 0abd3a674e..731c842f3d 100644 --- a/include/asm-sparc64/head.h +++ b/include/asm-sparc64/head.h @@ -10,6 +10,7 @@ #define __CHEETAH_ID 0x003e0014 #define __JALAPENO_ID 0x003e0016 +#define __SERRANO_ID 0x003e0022 #define CHEETAH_MANUF 0x003e #define CHEETAH_IMPL 0x0014 /* Ultra-III */ diff --git a/include/asm-sparc64/smp.h b/include/asm-sparc64/smp.h index 473edb2603..ad1d35a7d1 100644 --- a/include/asm-sparc64/smp.h +++ b/include/asm-sparc64/smp.h @@ -37,33 +37,7 @@ extern cpumask_t phys_cpu_present_map; * General functions that each host system must provide. */ -static __inline__ int hard_smp_processor_id(void) -{ - if (tlb_type == cheetah || tlb_type == cheetah_plus) { - unsigned long cfg, ver; - __asm__ __volatile__("rdpr %%ver, %0" : "=r" (ver)); - if ((ver >> 32) == 0x003e0016) { - __asm__ __volatile__("ldxa [%%g0] %1, %0" - : "=r" (cfg) - : "i" (ASI_JBUS_CONFIG)); - return ((cfg >> 17) & 0x1f); - } else { - __asm__ __volatile__("ldxa [%%g0] %1, %0" - : "=r" (cfg) - : "i" (ASI_SAFARI_CONFIG)); - return ((cfg >> 17) & 0x3ff); - } - } else if (this_is_starfire != 0) { - return starfire_hard_smp_processor_id(); - } else { - unsigned long upaconfig; - __asm__ __volatile__("ldxa [%%g0] %1, %0" - : "=r" (upaconfig) - : "i" (ASI_UPA_CONFIG)); - return ((upaconfig >> 17) & 0x1f); - } -} - +extern int hard_smp_processor_id(void); #define raw_smp_processor_id() (current_thread_info()->cpu) extern void smp_setup_cpu_possible_map(void); -- cgit v1.2.2 From ffe483d55229fadbaf4cc7316d47024a24ecd1a2 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 2 Feb 2006 21:55:10 -0800 Subject: [SPARC64]: Add explicit register args to trap state loading macros. This, as well as making the code cleaner, allows a simplification in the TSB miss handling path. Signed-off-by: David S. Miller --- include/asm-sparc64/cpudata.h | 88 +++++++++++++++++++++---------------------- 1 file changed, 44 insertions(+), 44 deletions(-) (limited to 'include') diff --git a/include/asm-sparc64/cpudata.h b/include/asm-sparc64/cpudata.h index da54b4f354..c15514f82c 100644 --- a/include/asm-sparc64/cpudata.h +++ b/include/asm-sparc64/cpudata.h @@ -107,67 +107,67 @@ extern struct cpuid_patch_entry __cpuid_patch, __cpuid_patch_end; lduwa [REG] ASI_PHYS_BYPASS_EC_E, REG;\ .previous; -/* Clobbers %g1, current address space PGD phys address into %g7. */ -#define TRAP_LOAD_PGD_PHYS \ - __GET_CPUID(%g1) \ - sethi %hi(trap_block), %g7; \ - sllx %g1, TRAP_BLOCK_SZ_SHIFT, %g1; \ - or %g7, %lo(trap_block), %g7; \ - add %g7, %g1, %g7; \ - ldx [%g7 + TRAP_PER_CPU_PGD_PADDR], %g7; - -/* Clobbers %g1, loads local processor's IRQ work area into %g6. */ -#define TRAP_LOAD_IRQ_WORK \ - __GET_CPUID(%g1) \ - sethi %hi(__irq_work), %g6; \ - sllx %g1, 6, %g1; \ - or %g6, %lo(__irq_work), %g6; \ - add %g6, %g1, %g6; - -/* Clobbers %g1, loads %g6 with current thread info pointer. */ -#define TRAP_LOAD_THREAD_REG \ - __GET_CPUID(%g1) \ - sethi %hi(trap_block), %g6; \ - sllx %g1, TRAP_BLOCK_SZ_SHIFT, %g1; \ - or %g6, %lo(trap_block), %g6; \ - ldx [%g6 + %g1], %g6; - -/* Given the current thread info pointer in %g6, load the per-cpu - * area base of the current processor into %g5. REG1, REG2, and REG3 are +/* Clobbers TMP, current address space PGD phys address into DEST. */ +#define TRAP_LOAD_PGD_PHYS(DEST, TMP) \ + __GET_CPUID(TMP) \ + sethi %hi(trap_block), DEST; \ + sllx TMP, TRAP_BLOCK_SZ_SHIFT, TMP; \ + or DEST, %lo(trap_block), DEST; \ + add DEST, TMP, DEST; \ + ldx [DEST + TRAP_PER_CPU_PGD_PADDR], DEST; + +/* Clobbers TMP, loads local processor's IRQ work area into DEST. */ +#define TRAP_LOAD_IRQ_WORK(DEST, TMP) \ + __GET_CPUID(TMP) \ + sethi %hi(__irq_work), DEST; \ + sllx TMP, 6, TMP; \ + or DEST, %lo(__irq_work), DEST; \ + add DEST, TMP, DEST; + +/* Clobbers TMP, loads DEST with current thread info pointer. */ +#define TRAP_LOAD_THREAD_REG(DEST, TMP) \ + __GET_CPUID(TMP) \ + sethi %hi(trap_block), DEST; \ + sllx TMP, TRAP_BLOCK_SZ_SHIFT, TMP; \ + or DEST, %lo(trap_block), DEST; \ + ldx [DEST + TMP], DEST; + +/* Given the current thread info pointer in THR, load the per-cpu + * area base of the current processor into DEST. REG1, REG2, and REG3 are * clobbered. * - * You absolutely cannot use %g5 as a temporary in this code. The + * You absolutely cannot use DEST as a temporary in this code. The * reason is that traps can happen during execution, and return from - * trap will load the fully resolved %g5 per-cpu base. This can corrupt + * trap will load the fully resolved DEST per-cpu base. This can corrupt * the calculations done by the macro mid-stream. */ -#define LOAD_PER_CPU_BASE(REG1, REG2, REG3) \ - ldub [%g6 + TI_CPU], REG1; \ +#define LOAD_PER_CPU_BASE(DEST, THR, REG1, REG2, REG3) \ + ldub [THR + TI_CPU], REG1; \ sethi %hi(__per_cpu_shift), REG3; \ sethi %hi(__per_cpu_base), REG2; \ ldx [REG3 + %lo(__per_cpu_shift)], REG3; \ ldx [REG2 + %lo(__per_cpu_base)], REG2; \ sllx REG1, REG3, REG3; \ - add REG3, REG2, %g5; + add REG3, REG2, DEST; #else /* Uniprocessor versions, we know the cpuid is zero. */ -#define TRAP_LOAD_PGD_PHYS \ - sethi %hi(trap_block), %g7; \ - or %g7, %lo(trap_block), %g7; \ - ldx [%g7 + TRAP_PER_CPU_PGD_PADDR], %g7; +#define TRAP_LOAD_PGD_PHYS(DEST, TMP) \ + sethi %hi(trap_block), DEST; \ + or DEST, %lo(trap_block), DEST; \ + ldx [DEST + TRAP_PER_CPU_PGD_PADDR], DEST; -#define TRAP_LOAD_IRQ_WORK \ - sethi %hi(__irq_work), %g6; \ - or %g6, %lo(__irq_work), %g6; +#define TRAP_LOAD_IRQ_WORK(DEST, TMP) \ + sethi %hi(__irq_work), DEST; \ + or DEST, %lo(__irq_work), DEST; -#define TRAP_LOAD_THREAD_REG \ - sethi %hi(trap_block), %g6; \ - ldx [%g6 + %lo(trap_block)], %g6; +#define TRAP_LOAD_THREAD_REG(DEST, TMP) \ + sethi %hi(trap_block), DEST; \ + ldx [DEST + %lo(trap_block)], DEST; -/* No per-cpu areas on uniprocessor, so no need to load %g5. */ -#define LOAD_PER_CPU_BASE(REG1, REG2, REG3) +/* No per-cpu areas on uniprocessor, so no need to load DEST. */ +#define LOAD_PER_CPU_BASE(DEST, THR, REG1, REG2, REG3) #endif /* !(CONFIG_SMP) */ -- cgit v1.2.2 From 314ef6859750b6539eac48d78059bb7986f29cb1 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sat, 4 Feb 2006 00:10:01 -0800 Subject: [SPARC64]: Refine register window trap handling. When saving and restoing trap state, do the window spill/fill handling inline so that we never trap deeper than 2 trap levels. This is important for chips like Niagara. The window fixup code is massively simplified, and many more improvements are now possible. Signed-off-by: David S. Miller --- include/asm-sparc64/ttable.h | 234 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 233 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/asm-sparc64/ttable.h b/include/asm-sparc64/ttable.h index f557db4faf..f912f52c0c 100644 --- a/include/asm-sparc64/ttable.h +++ b/include/asm-sparc64/ttable.h @@ -93,7 +93,7 @@ #define SYSCALL_TRAP(routine, systbl) \ sethi %hi(109f), %g7; \ - ba,pt %xcc, scetrap; \ + ba,pt %xcc, etrap; \ 109: or %g7, %lo(109b), %g7; \ sethi %hi(systbl), %l7; \ ba,pt %xcc, routine; \ @@ -219,6 +219,31 @@ saved; retry; nop; nop; nop; nop; nop; nop; \ nop; nop; nop; nop; nop; nop; nop; nop; +#define SPILL_0_NORMAL_ETRAP \ +etrap_kernel_spill: \ + stx %l0, [%sp + STACK_BIAS + 0x00]; \ + stx %l1, [%sp + STACK_BIAS + 0x08]; \ + stx %l2, [%sp + STACK_BIAS + 0x10]; \ + stx %l3, [%sp + STACK_BIAS + 0x18]; \ + stx %l4, [%sp + STACK_BIAS + 0x20]; \ + stx %l5, [%sp + STACK_BIAS + 0x28]; \ + stx %l6, [%sp + STACK_BIAS + 0x30]; \ + stx %l7, [%sp + STACK_BIAS + 0x38]; \ + stx %i0, [%sp + STACK_BIAS + 0x40]; \ + stx %i1, [%sp + STACK_BIAS + 0x48]; \ + stx %i2, [%sp + STACK_BIAS + 0x50]; \ + stx %i3, [%sp + STACK_BIAS + 0x58]; \ + stx %i4, [%sp + STACK_BIAS + 0x60]; \ + stx %i5, [%sp + STACK_BIAS + 0x68]; \ + stx %i6, [%sp + STACK_BIAS + 0x70]; \ + stx %i7, [%sp + STACK_BIAS + 0x78]; \ + saved; \ + sub %g1, 2, %g1; \ + ba,pt %xcc, etrap_save; \ + wrpr %g1, %cwp; \ + nop; nop; nop; nop; nop; nop; nop; nop; \ + nop; nop; nop; nop; + /* Normal 64bit spill */ #define SPILL_1_GENERIC(ASI) \ add %sp, STACK_BIAS + 0x00, %g1; \ @@ -252,6 +277,67 @@ b,a,pt %xcc, spill_fixup_mna; \ b,a,pt %xcc, spill_fixup; +#define SPILL_1_GENERIC_ETRAP \ +etrap_user_spill_64bit: \ + stxa %l0, [%sp + STACK_BIAS + 0x00] %asi; \ + stxa %l1, [%sp + STACK_BIAS + 0x08] %asi; \ + stxa %l2, [%sp + STACK_BIAS + 0x10] %asi; \ + stxa %l3, [%sp + STACK_BIAS + 0x18] %asi; \ + stxa %l4, [%sp + STACK_BIAS + 0x20] %asi; \ + stxa %l5, [%sp + STACK_BIAS + 0x28] %asi; \ + stxa %l6, [%sp + STACK_BIAS + 0x30] %asi; \ + stxa %l7, [%sp + STACK_BIAS + 0x38] %asi; \ + stxa %i0, [%sp + STACK_BIAS + 0x40] %asi; \ + stxa %i1, [%sp + STACK_BIAS + 0x48] %asi; \ + stxa %i2, [%sp + STACK_BIAS + 0x50] %asi; \ + stxa %i3, [%sp + STACK_BIAS + 0x58] %asi; \ + stxa %i4, [%sp + STACK_BIAS + 0x60] %asi; \ + stxa %i5, [%sp + STACK_BIAS + 0x68] %asi; \ + stxa %i6, [%sp + STACK_BIAS + 0x70] %asi; \ + stxa %i7, [%sp + STACK_BIAS + 0x78] %asi; \ + saved; \ + sub %g1, 2, %g1; \ + ba,pt %xcc, etrap_save; \ + wrpr %g1, %cwp; \ + nop; nop; nop; nop; nop; \ + nop; nop; nop; nop; \ + ba,a,pt %xcc, etrap_spill_fixup_64bit; \ + ba,a,pt %xcc, etrap_spill_fixup_64bit; \ + ba,a,pt %xcc, etrap_spill_fixup_64bit; + +#define SPILL_1_GENERIC_ETRAP_FIXUP \ +etrap_spill_fixup_64bit: \ + ldub [%g6 + TI_WSAVED], %g1; \ + sll %g1, 3, %g3; \ + add %g6, %g3, %g3; \ + stx %sp, [%g3 + TI_RWIN_SPTRS]; \ + sll %g1, 7, %g3; \ + add %g6, %g3, %g3; \ + stx %l0, [%g3 + TI_REG_WINDOW + 0x00]; \ + stx %l1, [%g3 + TI_REG_WINDOW + 0x08]; \ + stx %l2, [%g3 + TI_REG_WINDOW + 0x10]; \ + stx %l3, [%g3 + TI_REG_WINDOW + 0x18]; \ + stx %l4, [%g3 + TI_REG_WINDOW + 0x20]; \ + stx %l5, [%g3 + TI_REG_WINDOW + 0x28]; \ + stx %l6, [%g3 + TI_REG_WINDOW + 0x30]; \ + stx %l7, [%g3 + TI_REG_WINDOW + 0x38]; \ + stx %i0, [%g3 + TI_REG_WINDOW + 0x40]; \ + stx %i1, [%g3 + TI_REG_WINDOW + 0x48]; \ + stx %i2, [%g3 + TI_REG_WINDOW + 0x50]; \ + stx %i3, [%g3 + TI_REG_WINDOW + 0x58]; \ + stx %i4, [%g3 + TI_REG_WINDOW + 0x60]; \ + stx %i5, [%g3 + TI_REG_WINDOW + 0x68]; \ + stx %i6, [%g3 + TI_REG_WINDOW + 0x70]; \ + stx %i7, [%g3 + TI_REG_WINDOW + 0x78]; \ + add %g1, 1, %g1; \ + stb %g1, [%g6 + TI_WSAVED]; \ + saved; \ + rdpr %cwp, %g1; \ + sub %g1, 2, %g1; \ + ba,pt %xcc, etrap_save; \ + wrpr %g1, %cwp; \ + nop; nop; nop + /* Normal 32bit spill */ #define SPILL_2_GENERIC(ASI) \ srl %sp, 0, %sp; \ @@ -285,6 +371,68 @@ b,a,pt %xcc, spill_fixup_mna; \ b,a,pt %xcc, spill_fixup; +#define SPILL_2_GENERIC_ETRAP \ +etrap_user_spill_32bit: \ + srl %sp, 0, %sp; \ + stwa %l0, [%sp + 0x00] %asi; \ + stwa %l1, [%sp + 0x04] %asi; \ + stwa %l2, [%sp + 0x08] %asi; \ + stwa %l3, [%sp + 0x0c] %asi; \ + stwa %l4, [%sp + 0x10] %asi; \ + stwa %l5, [%sp + 0x14] %asi; \ + stwa %l6, [%sp + 0x18] %asi; \ + stwa %l7, [%sp + 0x1c] %asi; \ + stwa %i0, [%sp + 0x20] %asi; \ + stwa %i1, [%sp + 0x24] %asi; \ + stwa %i2, [%sp + 0x28] %asi; \ + stwa %i3, [%sp + 0x2c] %asi; \ + stwa %i4, [%sp + 0x30] %asi; \ + stwa %i5, [%sp + 0x34] %asi; \ + stwa %i6, [%sp + 0x38] %asi; \ + stwa %i7, [%sp + 0x3c] %asi; \ + saved; \ + sub %g1, 2, %g1; \ + ba,pt %xcc, etrap_save; \ + wrpr %g1, %cwp; \ + nop; nop; nop; nop; \ + nop; nop; nop; nop; \ + ba,a,pt %xcc, etrap_spill_fixup_32bit; \ + ba,a,pt %xcc, etrap_spill_fixup_32bit; \ + ba,a,pt %xcc, etrap_spill_fixup_32bit; + +#define SPILL_2_GENERIC_ETRAP_FIXUP \ +etrap_spill_fixup_32bit: \ + ldub [%g6 + TI_WSAVED], %g1; \ + sll %g1, 3, %g3; \ + add %g6, %g3, %g3; \ + stx %sp, [%g3 + TI_RWIN_SPTRS]; \ + sll %g1, 7, %g3; \ + add %g6, %g3, %g3; \ + stw %l0, [%g3 + TI_REG_WINDOW + 0x00]; \ + stw %l1, [%g3 + TI_REG_WINDOW + 0x04]; \ + stw %l2, [%g3 + TI_REG_WINDOW + 0x08]; \ + stw %l3, [%g3 + TI_REG_WINDOW + 0x0c]; \ + stw %l4, [%g3 + TI_REG_WINDOW + 0x10]; \ + stw %l5, [%g3 + TI_REG_WINDOW + 0x14]; \ + stw %l6, [%g3 + TI_REG_WINDOW + 0x18]; \ + stw %l7, [%g3 + TI_REG_WINDOW + 0x1c]; \ + stw %i0, [%g3 + TI_REG_WINDOW + 0x20]; \ + stw %i1, [%g3 + TI_REG_WINDOW + 0x24]; \ + stw %i2, [%g3 + TI_REG_WINDOW + 0x28]; \ + stw %i3, [%g3 + TI_REG_WINDOW + 0x2c]; \ + stw %i4, [%g3 + TI_REG_WINDOW + 0x30]; \ + stw %i5, [%g3 + TI_REG_WINDOW + 0x34]; \ + stw %i6, [%g3 + TI_REG_WINDOW + 0x38]; \ + stw %i7, [%g3 + TI_REG_WINDOW + 0x3c]; \ + add %g1, 1, %g1; \ + stb %g1, [%g6 + TI_WSAVED]; \ + saved; \ + rdpr %cwp, %g1; \ + sub %g1, 2, %g1; \ + ba,pt %xcc, etrap_save; \ + wrpr %g1, %cwp; \ + nop; nop; nop + #define SPILL_1_NORMAL SPILL_1_GENERIC(ASI_AIUP) #define SPILL_2_NORMAL SPILL_2_GENERIC(ASI_AIUP) #define SPILL_3_NORMAL SPILL_0_NORMAL @@ -323,6 +471,35 @@ restored; retry; nop; nop; nop; nop; nop; nop; \ nop; nop; nop; nop; nop; nop; nop; nop; +#define FILL_0_NORMAL_RTRAP \ +kern_rtt_fill: \ + rdpr %cwp, %g1; \ + sub %g1, 1, %g1; \ + wrpr %g1, %cwp; \ + ldx [%sp + STACK_BIAS + 0x00], %l0; \ + ldx [%sp + STACK_BIAS + 0x08], %l1; \ + ldx [%sp + STACK_BIAS + 0x10], %l2; \ + ldx [%sp + STACK_BIAS + 0x18], %l3; \ + ldx [%sp + STACK_BIAS + 0x20], %l4; \ + ldx [%sp + STACK_BIAS + 0x28], %l5; \ + ldx [%sp + STACK_BIAS + 0x30], %l6; \ + ldx [%sp + STACK_BIAS + 0x38], %l7; \ + ldx [%sp + STACK_BIAS + 0x40], %i0; \ + ldx [%sp + STACK_BIAS + 0x48], %i1; \ + ldx [%sp + STACK_BIAS + 0x50], %i2; \ + ldx [%sp + STACK_BIAS + 0x58], %i3; \ + ldx [%sp + STACK_BIAS + 0x60], %i4; \ + ldx [%sp + STACK_BIAS + 0x68], %i5; \ + ldx [%sp + STACK_BIAS + 0x70], %i6; \ + ldx [%sp + STACK_BIAS + 0x78], %i7; \ + restored; \ + add %g1, 1, %g1; \ + ba,pt %xcc, kern_rtt_restore; \ + wrpr %g1, %cwp; \ + nop; nop; nop; nop; nop; \ + nop; nop; nop; nop; + + /* Normal 64bit fill */ #define FILL_1_GENERIC(ASI) \ add %sp, STACK_BIAS + 0x00, %g1; \ @@ -354,6 +531,33 @@ b,a,pt %xcc, fill_fixup_mna; \ b,a,pt %xcc, fill_fixup; +#define FILL_1_GENERIC_RTRAP \ +user_rtt_fill_64bit: \ + ldxa [%sp + STACK_BIAS + 0x00] %asi, %l0; \ + ldxa [%sp + STACK_BIAS + 0x08] %asi, %l1; \ + ldxa [%sp + STACK_BIAS + 0x10] %asi, %l2; \ + ldxa [%sp + STACK_BIAS + 0x18] %asi, %l3; \ + ldxa [%sp + STACK_BIAS + 0x20] %asi, %l4; \ + ldxa [%sp + STACK_BIAS + 0x28] %asi, %l5; \ + ldxa [%sp + STACK_BIAS + 0x30] %asi, %l6; \ + ldxa [%sp + STACK_BIAS + 0x38] %asi, %l7; \ + ldxa [%sp + STACK_BIAS + 0x40] %asi, %i0; \ + ldxa [%sp + STACK_BIAS + 0x48] %asi, %i1; \ + ldxa [%sp + STACK_BIAS + 0x50] %asi, %i2; \ + ldxa [%sp + STACK_BIAS + 0x58] %asi, %i3; \ + ldxa [%sp + STACK_BIAS + 0x60] %asi, %i4; \ + ldxa [%sp + STACK_BIAS + 0x68] %asi, %i5; \ + ldxa [%sp + STACK_BIAS + 0x70] %asi, %i6; \ + ldxa [%sp + STACK_BIAS + 0x78] %asi, %i7; \ + ba,pt %xcc, user_rtt_pre_restore; \ + restored; \ + nop; nop; nop; nop; nop; nop; \ + nop; nop; nop; nop; nop; \ + ba,a,pt %xcc, user_rtt_fill_fixup; \ + ba,a,pt %xcc, user_rtt_fill_fixup; \ + ba,a,pt %xcc, user_rtt_fill_fixup; + + /* Normal 32bit fill */ #define FILL_2_GENERIC(ASI) \ srl %sp, 0, %sp; \ @@ -385,6 +589,34 @@ b,a,pt %xcc, fill_fixup_mna; \ b,a,pt %xcc, fill_fixup; +#define FILL_2_GENERIC_RTRAP \ +user_rtt_fill_32bit: \ + srl %sp, 0, %sp; \ + lduwa [%sp + 0x00] %asi, %l0; \ + lduwa [%sp + 0x04] %asi, %l1; \ + lduwa [%sp + 0x08] %asi, %l2; \ + lduwa [%sp + 0x0c] %asi, %l3; \ + lduwa [%sp + 0x10] %asi, %l4; \ + lduwa [%sp + 0x14] %asi, %l5; \ + lduwa [%sp + 0x18] %asi, %l6; \ + lduwa [%sp + 0x1c] %asi, %l7; \ + lduwa [%sp + 0x20] %asi, %i0; \ + lduwa [%sp + 0x24] %asi, %i1; \ + lduwa [%sp + 0x28] %asi, %i2; \ + lduwa [%sp + 0x2c] %asi, %i3; \ + lduwa [%sp + 0x30] %asi, %i4; \ + lduwa [%sp + 0x34] %asi, %i5; \ + lduwa [%sp + 0x38] %asi, %i6; \ + lduwa [%sp + 0x3c] %asi, %i7; \ + ba,pt %xcc, user_rtt_pre_restore; \ + restored; \ + nop; nop; nop; nop; nop; \ + nop; nop; nop; nop; nop; \ + ba,a,pt %xcc, user_rtt_fill_fixup; \ + ba,a,pt %xcc, user_rtt_fill_fixup; \ + ba,a,pt %xcc, user_rtt_fill_fixup; + + #define FILL_1_NORMAL FILL_1_GENERIC(ASI_AIUP) #define FILL_2_NORMAL FILL_2_GENERIC(ASI_AIUP) #define FILL_3_NORMAL FILL_0_NORMAL -- cgit v1.2.2 From 766f861fbbd968a1850295ed6dec4504b4500dcc Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sat, 4 Feb 2006 03:01:45 -0800 Subject: [SPARC64]: SUN4V hypervisor interface defines. Signed-off-by: David S. Miller --- include/asm-sparc64/hypervisor.h | 2072 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 2072 insertions(+) create mode 100644 include/asm-sparc64/hypervisor.h (limited to 'include') diff --git a/include/asm-sparc64/hypervisor.h b/include/asm-sparc64/hypervisor.h new file mode 100644 index 0000000000..9c8e453abe --- /dev/null +++ b/include/asm-sparc64/hypervisor.h @@ -0,0 +1,2072 @@ +#ifndef _SPARC64_HYPERVISOR_H +#define _SPARC64_HYPERVISOR_H + +/* Sun4v hypervisor interfaces and defines. + * + * Hypervisor calls are made via traps to software traps number 0x80 + * and above. Registers %o0 to %o5 serve as argument, status, and + * return value registers. + * + * There are two kinds of these traps. First there are the normal + * "fast traps" which use software trap 0x80 and encode the function + * to invoke by number in register %o5. Argument and return value + * handling is as follows: + * + * ----------------------------------------------- + * | %o5 | function number | undefined | + * | %o0 | argument 0 | return status | + * | %o1 | argument 1 | return value 1 | + * | %o2 | argument 2 | return value 2 | + * | %o3 | argument 3 | return value 3 | + * | %o4 | argument 4 | return value 4 | + * ----------------------------------------------- + * + * The second type are "hyper-fast traps" which encode the function + * number in the software trap number itself. So these use trap + * numbers > 0x80. The register usage for hyper-fast traps is as + * follows: + * + * ----------------------------------------------- + * | %o0 | argument 0 | return status | + * | %o1 | argument 1 | return value 1 | + * | %o2 | argument 2 | return value 2 | + * | %o3 | argument 3 | return value 3 | + * | %o4 | argument 4 | return value 4 | + * ----------------------------------------------- + * + * Registers providing explicit arguments to the hypervisor calls + * are volatile across the call. Upon return their values are + * undefined unless explicitly specified as containing a particular + * return value by the specific call. The return status is always + * returned in register %o0, zero indicates a successful execution of + * the hypervisor call and other values indicate an error status as + * defined below. So, for example, if a hyper-fast trap takes + * arguments 0, 1, and 2, then %o0, %o1, and %o2 are volatile across + * the call and %o3, %o4, and %o5 would be preserved. + * + * If the hypervisor trap is invalid, or the fast trap function number + * is invalid, HV_EBADTRAP will be returned in %o0. Also, all 64-bits + * of the argument and return values are significant. + */ + +/* Trap numbers. */ +#define HV_FAST_TRAP 0x80 +#define HV_MMU_MAP_ADDR_TRAP 0x83 +#define HV_MMU_UNMAP_ADDR_TRAP 0x84 +#define HV_TTRACE_ADDENTRY_TRAP 0x85 +#define HV_CORE_TRAP 0xff + +/* Error codes. */ +#define HV_EOK 0 /* Successful return */ +#define HV_ENOCPU 1 /* Invalid CPU id */ +#define HV_ENORADDR 2 /* Invalid real address */ +#define HV_ENOINTR 3 /* Invalid interrupt id */ +#define HV_EBADPGSZ 4 /* Invalid pagesize encoding */ +#define HV_EBADTSB 5 /* Invalid TSB description */ +#define HV_EINVAL 6 /* Invalid argument */ +#define HV_EBADTRAP 7 /* Invalid function number */ +#define HV_EBADALIGN 8 /* Invalid address alignment */ +#define HV_EWOULDBLOCK 9 /* Cannot complete w/o blocking */ +#define HV_ENOACCESS 10 /* No access to resource */ +#define HV_EIO 11 /* I/O error */ +#define HV_ECPUERROR 12 /* CPU in error state */ +#define HV_ENOTSUPPORTED 13 /* Function not supported */ +#define HV_ENOMAP 14 /* No mapping found */ +#define HV_ETOOMANY 15 /* Too many items specified */ + +/* mach_exit() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_MACH_EXIT + * ARG0: exit code + * ERRORS: This service does not return. + * + * Stop all CPUs in the virtual domain and place them into the stopped + * state. The 64-bit exit code may be passed to a service entity as + * the domain's exit status. On systems without a service entity, the + * domain will undergo a reset, and the boot firmware will be + * reloaded. + * + * This function will never return to the guest that invokes it. + * + * Note: By convention an exit code of zero denotes a successful exit by + * the guest code. A non-zero exit code denotes a guest specific + * error indication. + * + */ +#define HV_FAST_MACH_EXIT 0x00 + +/* Domain services. */ + +/* mach_desc() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_MACH_DESC + * ARG0: buffer + * ARG1: length + * RET0: status + * RET1: length + * ERRORS: HV_EBADALIGN Buffer is badly aligned + * HV_ENORADDR Buffer is to an illegal real address. + * HV_EINVAL Buffer length is too small for complete + * machine description. + * + * Copy the most current machine description into the buffer indicated + * by the real address in ARG0. The buffer provided must be 16 byte + * aligned. Upon success or HV_EINVAL, this service returns the + * actual size of the machine description in the RET1 return value. + * + * Note: A method of determining the appropriate buffer size for the + * machine description is to first call this service with a buffer + * length of 0 bytes. + */ +#define HV_FAST_MACH_DESC 0x01 + +/* mach_exit() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_MACH_SIR + * ERRORS: This service does not return. + * + * Perform a software initiated reset of the virtual machine domain. + * All CPUs are captured as soon as possible, all hardware devices are + * returned to the entry default state, and the domain is restarted at + * the SIR (trap type 0x04) real trap table (RTBA) entry point on one + * of the CPUs. The single CPU restarted is selected as determined by + * platform specific policy. Memory is preserved across this + * operation. + */ +#define HV_FAST_MACH_SIR 0x02 + +/* mach_set_soft_state() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_MACH_SET_SOFT_STATE + * ARG0: software state + * ARG1: software state description pointer + * RET0: status + * ERRORS: EINVAL software state not valid or software state + * description is not NULL terminated + * ENORADDR software state description pointer is not a + * valid real address + * EBADALIGNED software state description is not correctly + * aligned + * + * This allows the guest to report it's soft state to the hypervisor. There + * are two primary components to this state. The first part states whether + * the guest software is running or not. The second containts optional + * details specific to the software. + * + * The software state argument is defined below in HV_SOFT_STATE_*, and + * indicates whether the guest is operating normally or in a transitional + * state. + * + * The software state description argument is a real address of a data buffer + * of size 32-bytes aligned on a 32-byte boundary. It is treated as a NULL + * terminated 7-bit ASCII string of up to 31 characters not including the + * NULL termination. + */ +#define HV_FAST_MACH_SET_SOFT_STATE 0x03 +#define HV_SOFT_STATE_NORMAL 0x01 +#define HV_SOFT_STATE_TRANSITION 0x02 + +/* mach_get_soft_state() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_MACH_GET_SOFT_STATE + * ARG0: software state description pointer + * RET0: status + * RET1: software state + * ERRORS: ENORADDR software state description pointer is not a + * valid real address + * EBADALIGNED software state description is not correctly + * aligned + * + * Retrieve the current value of the guest's software state. The rules + * for the software state pointer are the same as for mach_set_soft_state() + * above. + */ +#define HV_FAST_MACH_GET_SOFT_STATE 0x04 + +/* CPU services. + * + * CPUs represent devices that can execute software threads. A single + * chip that contains multiple cores or strands is represented as + * multiple CPUs with unique CPU identifiers. CPUs are exported to + * OBP via the machine description (and to the OS via the OBP device + * tree). CPUs are always in one of three states: stopped, running, + * or error. + * + * A CPU ID is a pre-assigned 16-bit value that uniquely identifies a + * CPU within a logical domain. Operations that are to be performed + * on multiple CPUs specify them via a CPU list. A CPU list is an + * array in real memory, of which each 16-bit word is a CPU ID. CPU + * lists are passed through the API as two arguments. The first is + * the number of entries (16-bit words) in the CPU list, and the + * second is the (real address) pointer to the CPU ID list. + */ + +/* cpu_start() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_CPU_START + * ARG0: CPU ID + * ARG1: PC + * ARG1: RTBA + * ARG1: target ARG0 + * RET0: status + * ERRORS: ENOCPU Invalid CPU ID + * EINVAL Target CPU ID is not in the stopped state + * ENORADDR Invalid PC or RTBA real address + * EBADALIGN Unaligned PC or unaligned RTBA + * EWOULDBLOCK Starting resources are not available + * + * Start CPU with given CPU ID with PC in %pc and with a real trap + * base address value of RTBA. The indicated CPU must be in the + * stopped state. The supplied RTBA must be aligned on a 256 byte + * boundary. On successful completion, the specified CPU will be in + * the running state and will be supplied with "target ARG0" in %o0 + * and RTBA in %tba. + */ +#define HV_FAST_CPU_START 0x10 + +/* cpu_stop() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_CPU_STOP + * ARG0: CPU ID + * RET0: status + * ERRORS: ENOCPU Invalid CPU ID + * EINVAL Target CPU ID is the current cpu + * EINVAL Target CPU ID is not in the running state + * EWOULDBLOCK Stopping resources are not available + * ENOTSUPPORTED Not supported on this platform + * + * The specified CPU is stopped. The indicated CPU must be in the + * running state. On completion, it will be in the stopped state. It + * is not legal to stop the current CPU. + * + * Note: As this service cannot be used to stop the current cpu, this service + * may not be used to stop the last running CPU in a domain. To stop + * and exit a running domain, a guest must use the mach_exit() service. + */ +#define HV_FAST_CPU_STOP 0x11 + +/* cpu_yield() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_CPU_YIELD + * RET0: status + * ERRORS: No possible error. + * + * Suspend execution on the current CPU. Execution will resume when + * an interrupt (device, %stick_compare, or cross-call) is targeted to + * the CPU. On some CPUs, this API may be used by the hypervisor to + * save power by disabling hardware strands. + */ +#define HV_FAST_CPU_YIELD 0x12 + + +/* cpu_qconf() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_CPU_QCONF + * ARG0: queue + * ARG1: base real address + * ARG2: number of entries + * RET0: status + * ERRORS: ENORADDR Invalid base real address + * EINVAL Invalid queue or number of entries is less + * than 2 or too large. + * EBADALIGN Base real address is not correctly aligned + * for size. + * + * Configure the given queue to be placed at the givem base real + * address, with the given number of entries. The number of entries + * must be a power of 2. The base real address must be aligned + * exactly to match the queue size. Each queue entry is 64 bytes + * long, so for example a 32 entry queue must be aligned on a 2048 + * byte real address boundary. + * + * The specified queue is unconfigured is number of entries is given as zero. + * + * For the current version of this API service, the argument queue is defined + * as follows: + * queue description + * ----- ------------------------- + * 0x3c cpu mondo queue + * 0x3d device mondo queue + * 0x3e resumable error queue + * 0x3f non-resumable error queue + * + * Note: The maximum number of entries for each queue for a specific cpu may + * be determined from the machine description. + */ +#define HV_FAST_CPU_QCONF 0x14 +#define HV_CPU_QUEUE_CPU_MONDO 0x3c +#define HV_CPU_QUEUE_DEVICE_MONDO 0x3d +#define HV_CPU_QUEUE_RES_ERROR 0x3e +#define HV_CPU_QUEUE_NONRES_ERROR 0x3f + +/* cpu_qinfo() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_CPU_QINFO + * ARG0: queue + * RET0: status + * RET1: base real address + * RET1: number of entries + * ERRORS: EINVAL Invalid queue + * + * Return the configuration info for the given queue. The base real + * address and number of entries of the defined queue are returned. + * The queue argument values are the same as for cpu_qconf() above. + * + * If the specified queue is a valid queue number, but no queue has + * been defined, the number of entries will be set to zero and the + * base real address returned is undefined. + */ +#define HV_FAST_CPU_QINFO 0x15 + +/* cpu_mondo_send() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_CPU_MONDO_SEND + * ARG0-1: CPU list + * ARG2: data real address + * RET0: status + * ERRORS: EBADALIGN Mondo data is not 64-byte aligned or CPU list + * is not 2-byte aligned. + * ENORADDR Invalid data mondo address, or invalid cpu list + * address. + * ENOCPU Invalid cpu in CPU list + * EWOULDBLOCK Some or all of the listed CPUs did not receive + * the mondo + * EINVAL CPU list includes caller's CPU ID + * + * Send a mondo interrupt to the CPUs in the given CPU list with the + * 64-bytes at the given data real address. The data must be 64-byte + * aligned. The mondo data will be delivered to the cpu_mondo queues + * of the recipient CPUs. + * + * In all cases, error or not, the CPUs in the CPU list to which the + * mondo has been successfully delivered will be indicated by having + * their entry in CPU list updated with the value 0xffff. + */ +#define HV_FAST_CPU_MONDO_SEND 0x42 + +/* cpu_myid() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_CPU_MYID + * RET0: status + * RET1: CPU ID + * ERRORS: No errors defined. + * + * Return the hypervisor ID handle for the current CPU. Use by a + * virtual CPU to discover it's own identity. + */ +#define HV_FAST_CPU_MYID 0x16 + +/* cpu_state() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_CPU_STATE + * ARG0: CPU ID + * RET0: status + * RET1: state + * ERRORS: ENOCPU Invalid CPU ID + * + * Retrieve the current state of the CPU with the given CPU ID. + */ +#define HV_FAST_CPU_STATE 0x17 +#define HV_CPU_STATE_STOPPED 0x01 +#define HV_CPU_STATE_RUNNING 0x02 +#define HV_CPU_STATE_ERROR 0x03 + +/* cpu_set_rtba() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_CPU_SET_RTBA + * ARG0: RTBA + * RET0: status + * RET1: previous RTBA + * ERRORS: ENORADDR Invalid RTBA real address + * EBADALIGN RTBA is incorrectly aligned for a trap table + * + * Set the real trap base address of the local cpu to the given RTBA. + * The supplied RTBA must be aligned on a 256 byte boundary. Upon + * success the previous value of the RTBA is returned in RET1. + * + * Note: This service does not affect %tba + */ +#define HV_FAST_CPU_SET_RTBA 0x18 + +/* cpu_set_rtba() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_CPU_GET_RTBA + * RET0: status + * RET1: previous RTBA + * ERRORS: No possible error. + * + * Returns the current value of RTBA in RET1. + */ +#define HV_FAST_CPU_GET_RTBA 0x19 + +/* MMU services. + * + * Layout of a TSB description for mmu_tsb_ctx{,non}0() calls. + */ +#ifndef __ASSEMBLY__ +struct hv_tsb_descr { + unsigned short pgsz_idx; + unsigned short assoc; + unsigned int num_ttes; /* in TTEs */ + unsigned int ctx_idx; + unsigned int pgsz_mask; + unsigned long tsb_base; + unsigned long resv; +}; +#endif +#define HV_TSB_DESCR_PGSZ_IDX_OFFSET 0x00 +#define HV_TSB_DESCR_ASSOC_OFFSET 0x02 +#define HV_TSB_DESCR_NUM_TTES_OFFSET 0x04 +#define HV_TSB_DESCR_CTX_IDX_OFFSET 0x08 +#define HV_TSB_DESCR_PGSZ_MASK_OFFSET 0x0c +#define HV_TSB_DESCR_TSB_BASE_OFFSET 0x10 +#define HV_TSB_DESCR_RESV_OFFSET 0x18 + +/* Page size bitmask. */ +#define HV_PGSZ_MASK_8K (1 << 0) +#define HV_PGSZ_MASK_64K (1 << 1) +#define HV_PGSZ_MASK_512K (1 << 2) +#define HV_PGSZ_MASK_4MB (1 << 3) +#define HV_PGSZ_MASK_32MB (1 << 4) +#define HV_PGSZ_MASK_256MB (1 << 5) +#define HV_PGSZ_MASK_2GB (1 << 6) +#define HV_PGSZ_MASK_16GB (1 << 7) + +/* Page size index. The value given in the TSB descriptor must correspond + * to the smallest page size specified in the pgsz_mask page size bitmask. + */ +#define HV_PGSZ_IDX_8K 0 +#define HV_PGSZ_IDX_64K 1 +#define HV_PGSZ_IDX_512K 2 +#define HV_PGSZ_IDX_4MB 3 +#define HV_PGSZ_IDX_32MB 4 +#define HV_PGSZ_IDX_256MB 5 +#define HV_PGSZ_IDX_2GB 6 +#define HV_PGSZ_IDX_16GB 7 + +/* MMU fault status area. + * + * MMU related faults have their status and fault address information + * placed into a memory region made available by privileged code. Each + * virtual processor must make a mmu_fault_area_conf() call to tell the + * hypervisor where that processor's fault status should be stored. + * + * The fault status block is a multiple of 64-bytes and must be aligned + * on a 64-byte boundary. + */ +#ifndef __ASSEMBLY__ +struct hv_fault_status { + unsigned long i_fault_type; + unsigned long i_fault_addr; + unsigned long i_fault_ctx; + unsigned long i_reserved[5]; + unsigned long d_fault_type; + unsigned long d_fault_addr; + unsigned long d_fault_ctx; + unsigned long d_reserved[5]; +}; +#endif +#define HV_FAULT_I_TYPE_OFFSET 0x00 +#define HV_FAULT_I_ADDR_OFFSET 0x08 +#define HV_FAULT_I_CTX_OFFSET 0x10 +#define HV_FAULT_D_TYPE_OFFSET 0x40 +#define HV_FAULT_D_ADDR_OFFSET 0x48 +#define HV_FAULT_D_CTX_OFFSET 0x50 + +#define HV_FAULT_TYPE_FAST_MISS 1 +#define HV_FAULT_TYPE_FAST_PROT 2 +#define HV_FAULT_TYPE_MMU_MISS 3 +#define HV_FAULT_TYPE_INV_RA 4 +#define HV_FAULT_TYPE_PRIV_VIOL 5 +#define HV_FAULT_TYPE_PROT_VIOL 6 +#define HV_FAULT_TYPE_NFO 7 +#define HV_FAULT_TYPE_NFO_SEFF 8 +#define HV_FAULT_TYPE_INV_VA 9 +#define HV_FAULT_TYPE_INV_ASI 10 +#define HV_FAULT_TYPE_NC_ATOMIC 11 +#define HV_FAULT_TYPE_PRIV_ACT 12 +#define HV_FAULT_TYPE_RESV1 13 +#define HV_FAULT_TYPE_UNALIGNED 14 +#define HV_FAULT_TYPE_INV_PGSZ 15 +/* Values 16 --> -2 are reserved. */ +#define HV_FAULT_TYPE_MULTIPLE -1 + +/* Flags argument for mmu_{map,unmap}_addr(), mmu_demap_{page,context,all}(), + * and mmu_{map,unmap}_perm_addr(). + */ +#define HV_MMU_DMMU 0x01 +#define HV_MMU_IMMU 0x02 +#define HV_MMU_ALL (HV_MMU_DMMU | HV_MMU_IMMU) + +/* mmu_map_addr() + * TRAP: HV_MMU_MAP_ADDR_TRAP + * ARG0: virtual address + * ARG1: mmu context + * ARG2: TTE + * ARG3: flags (HV_MMU_{IMMU,DMMU}) + * ERRORS: EINVAL Invalid virtual address, mmu context, or flags + * EBADPGSZ Invalid page size value + * ENORADDR Invalid real address in TTE + * + * Create a non-permanent mapping using the given TTE, virtual + * address, and mmu context. The flags argument determines which + * (data, or instruction, or both) TLB the mapping gets loaded into. + * + * The behavior is undefined if the valid bit is clear in the TTE. + * + * Note: This API call is for privileged code to specify temporary translation + * mappings without the need to create and manage a TSB. + */ + +/* mmu_unmap_addr() + * TRAP: HV_MMU_UNMAP_ADDR_TRAP + * ARG0: virtual address + * ARG1: mmu context + * ARG2: flags (HV_MMU_{IMMU,DMMU}) + * ERRORS: EINVAL Invalid virtual address, mmu context, or flags + * + * Demaps the given virtual address in the given mmu context on this + * CPU. This function is intended to be used to demap pages mapped + * with mmu_map_addr. This service is equivalent to invoking + * mmu_demap_page() with only the current CPU in the CPU list. The + * flags argument determines which (data, or instruction, or both) TLB + * the mapping gets unmapped from. + * + * Attempting to perform an unmap operation for a previously defined + * permanent mapping will have undefined results. + */ + +/* mmu_tsb_ctx0() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_MMU_TSB_CTX0 + * ARG0: number of TSB descriptions + * ARG1: TSB descriptions pointer + * RET0: status + * ERRORS: ENORADDR Invalid TSB descriptions pointer or + * TSB base within a descriptor + * EBADALIGN TSB descriptions pointer is not aligned + * to an 8-byte boundary, or TSB base + * within a descriptor is not aligned for + * the given TSB size + * EBADPGSZ Invalid page size in a TSB descriptor + * EBADTSB Invalid associativity or size in a TSB + * descriptor + * EINVAL Invalid number of TSB descriptions, or + * invalid context index in a TSB + * descriptor, or index page size not + * equal to smallest page size in page + * size bitmask field. + * + * Configures the TSBs for the current CPU for virtual addresses with + * context zero. The TSB descriptions pointer is a pointer to an + * array of the given number of TSB descriptions. + * + * Note: The maximum number of TSBs available to a virtual CPU is given by the + * mmu-max-#tsbs property of the cpu's corresponding "cpu" node in the + * machine description. + */ +#define HV_FAST_MMU_TSB_CTX0 0x20 + +/* mmu_tsb_ctxnon0() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_MMU_TSB_CTXNON0 + * ARG0: number of TSB descriptions + * ARG1: TSB descriptions pointer + * RET0: status + * ERRORS: Same as for mmu_tsb_ctx0() above. + * + * Configures the TSBs for the current CPU for virtual addresses with + * non-zero contexts. The TSB descriptions pointer is a pointer to an + * array of the given number of TSB descriptions. + * + * Note: A maximum of 16 TSBs may be specified in the TSB description list. + */ +#define HV_FAST_MMU_TSB_CTXNON0 0x21 + +/* mmu_demap_page() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_MMU_DEMAP_PAGE + * ARG0: reserved, must be zero + * ARG1: reserved, must be zero + * ARG2: virtual address + * ARG3: mmu context + * ARG4: flags (HV_MMU_{IMMU,DMMU}) + * RET0: status + * ERRORS: EINVAL Invalid virutal address, context, or + * flags value + * ENOTSUPPORTED ARG0 or ARG1 is non-zero + * + * Demaps any page mapping of the given virtual address in the given + * mmu context for the current virtual CPU. Any virtually tagged + * caches are guaranteed to be kept consistent. The flags argument + * determines which TLB (instruction, or data, or both) participate in + * the operation. + * + * ARG0 and ARG1 are both reserved and must be set to zero. + */ +#define HV_FAST_MMU_DEMAP_PAGE 0x22 + +/* mmu_demap_ctx() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_MMU_DEMAP_CTX + * ARG0: reserved, must be zero + * ARG1: reserved, must be zero + * ARG2: mmu context + * ARG3: flags (HV_MMU_{IMMU,DMMU}) + * RET0: status + * ERRORS: EINVAL Invalid context or flags value + * ENOTSUPPORTED ARG0 or ARG1 is non-zero + * + * Demaps all non-permanent virtual page mappings previously specified + * for the given context for the current virtual CPU. Any virtual + * tagged caches are guaranteed to be kept consistent. The flags + * argument determines which TLB (instruction, or data, or both) + * participate in the operation. + * + * ARG0 and ARG1 are both reserved and must be set to zero. + */ +#define HV_FAST_MMU_DEMAP_CTX 0x23 + +/* mmu_demap_all() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_MMU_DEMAP_ALL + * ARG0: reserved, must be zero + * ARG1: reserved, must be zero + * ARG2: flags (HV_MMU_{IMMU,DMMU}) + * RET0: status + * ERRORS: EINVAL Invalid flags value + * ENOTSUPPORTED ARG0 or ARG1 is non-zero + * + * Demaps all non-permanent virtual page mappings previously specified + * for the current virtual CPU. Any virtual tagged caches are + * guaranteed to be kept consistent. The flags argument determines + * which TLB (instruction, or data, or both) participate in the + * operation. + * + * ARG0 and ARG1 are both reserved and must be set to zero. + */ +#define HV_FAST_MMU_DEMAP_ALL 0x24 + +/* mmu_map_perm_addr() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_MMU_MAP_PERM_ADDR + * ARG0: virtual address + * ARG1: reserved, must be zero + * ARG2: TTE + * ARG3: flags (HV_MMU_{IMMU,DMMU}) + * RET0: status + * ERRORS: EINVAL Invalid virutal address or flags value + * EBADPGSZ Invalid page size value + * ENORADDR Invalid real address in TTE + * ETOOMANY Too many mappings (max of 8 reached) + * + * Create a permanent mapping using the given TTE and virtual address + * for context 0 on the calling virtual CPU. A maximum of 8 such + * permanent mappings may be specified by privileged code. Mappings + * may be removed with mmu_unmap_perm_addr(). + * + * The behavior is undefined if a TTE with the valid bit clear is given. + * + * Note: This call is used to specify address space mappings for which + * privileged code does not expect to receive misses. For example, + * this mechanism can be used to map kernel nucleus code and data. + */ +#define HV_FAST_MMU_MAP_PERM_ADDR 0x25 + +/* mmu_fault_area_conf() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_MMU_FAULT_AREA_CONF + * ARG0: real address + * RET0: status + * RET1: previous mmu fault area real address + * ERRORS: ENORADDR Invalid real address + * EBADALIGN Invalid alignment for fault area + * + * Configure the MMU fault status area for the calling CPU. A 64-byte + * aligned real address specifies where MMU fault status information + * is placed. The return value is the previously specified area, or 0 + * for the first invocation. Specifying a fault area at real address + * 0 is not allowed. + */ +#define HV_FAST_MMU_FAULT_AREA_CONF 0x26 + +/* mmu_enable() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_MMU_ENABLE + * ARG0: enable flag + * ARG1: return target address + * RET0: status + * ERRORS: ENORADDR Invalid real address when disabling + * translation. + * EBADALIGN The return target address is not + * aligned to an instruction. + * EINVAL The enable flag request the current + * operating mode (e.g. disable if already + * disabled) + * + * Enable or disable virtual address translation for the calling CPU + * within the virtual machine domain. If the enable flag is zero, + * translation is disabled, any non-zero value will enable + * translation. + * + * When this function returns, the newly selected translation mode + * will be active. If the mmu is being enabled, then the return + * target address is a virtual address else it is a real address. + * + * Upon successful completion, control will be returned to the given + * return target address (ie. the cpu will jump to that address). On + * failure, the previous mmu mode remains and the trap simply returns + * as normal with the appropriate error code in RET0. + */ +#define HV_FAST_MMU_ENABLE 0x27 + +/* mmu_unmap_perm_addr() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_MMU_UNMAP_PERM_ADDR + * ARG0: virtual address + * ARG1: reserved, must be zero + * ARG2: flags (HV_MMU_{IMMU,DMMU}) + * RET0: status + * ERRORS: EINVAL Invalid virutal address or flags value + * ENOMAP Specified mapping was not found + * + * Demaps any permanent page mapping (established via + * mmu_map_perm_addr()) at the given virtual address for context 0 on + * the current virtual CPU. Any virtual tagged caches are guaranteed + * to be kept consistent. + */ +#define HV_FAST_MMU_UNMAP_PERM_ADDR 0x28 + +/* mmu_tsb_ctx0_info() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_MMU_TSB_CTX0_INFO + * ARG0: max TSBs + * ARG1: buffer pointer + * RET0: status + * RET1: number of TSBs + * ERRORS: EINVAL Supplied buffer is too small + * EBADALIGN The buffer pointer is badly aligned + * ENORADDR Invalid real address for buffer pointer + * + * Return the TSB configuration as previous defined by mmu_tsb_ctx0() + * into the provided buffer. The size of the buffer is given in ARG1 + * in terms of the number of TSB description entries. + * + * Upon return, RET1 always contains the number of TSB descriptions + * previously configured. If zero TSBs were configured, EOK is + * returned with RET1 containing 0. + */ +#define HV_FAST_MMU_TSB_CTX0_INFO 0x29 + +/* mmu_tsb_ctxnon0_info() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_MMU_TSB_CTXNON0_INFO + * ARG0: max TSBs + * ARG1: buffer pointer + * RET0: status + * RET1: number of TSBs + * ERRORS: EINVAL Supplied buffer is too small + * EBADALIGN The buffer pointer is badly aligned + * ENORADDR Invalid real address for buffer pointer + * + * Return the TSB configuration as previous defined by + * mmu_tsb_ctxnon0() into the provided buffer. The size of the buffer + * is given in ARG1 in terms of the number of TSB description entries. + * + * Upon return, RET1 always contains the number of TSB descriptions + * previously configured. If zero TSBs were configured, EOK is + * returned with RET1 containing 0. + */ +#define HV_FAST_MMU_TSB_CTXNON0_INFO 0x2a + +/* mmu_fault_area_info() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_MMU_FAULT_AREA_INFO + * RET0: status + * RET1: fault area real address + * ERRORS: No errors defined. + * + * Return the currently defined MMU fault status area for the current + * CPU. The real address of the fault status area is returned in + * RET1, or 0 is returned in RET1 if no fault status area is defined. + * + * Note: mmu_fault_area_conf() may be called with the return value (RET1) + * from this service if there is a need to save and restore the fault + * area for a cpu. + */ +#define HV_FAST_MMU_FAULT_AREA_INFO 0x2b + +/* Cache and Memory services. */ + +/* mem_scrub() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_MEM_SCRUB + * ARG0: real address + * ARG1: length + * RET0: status + * RET1: length scrubbed + * ERRORS: ENORADDR Invalid real address + * EBADALIGN Start address or length are not correctly + * aligned + * EINVAL Length is zero + * + * Zero the memory contents in the range real address to real address + * plus length minus 1. Also, valid ECC will be generated for that + * memory address range. Scrubbing is started at the given real + * address, but may not scrub the entire given length. The actual + * length scrubbed will be returned in RET1. + * + * The real address and length must be aligned on an 8K boundary, or + * contain the start address and length from a sun4v error report. + * + * Note: There are two uses for this function. The first use is to block clear + * and initialize memory and the second is to scrub an u ncorrectable + * error reported via a resumable or non-resumable trap. The second + * use requires the arguments to be equal to the real address and length + * provided in a sun4v memory error report. + */ +#define HV_FAST_MEM_SCRUB 0x31 + +/* mem_sync() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_MEM_SYNC + * ARG0: real address + * ARG1: length + * RET0: status + * RET1: length synced + * ERRORS: ENORADDR Invalid real address + * EBADALIGN Start address or length are not correctly + * aligned + * EINVAL Length is zero + * + * Force the next access within the real address to real address plus + * length minus 1 to be fetches from main system memory. Less than + * the given length may be synced, the actual amount synced is + * returned in RET1. The real address and length must be aligned on + * an 8K boundary. + */ +#define HV_FAST_MEM_SYNC 0x32 + +/* Time of day services. + * + * The hypervisor maintains the time of day on a per-domain basis. + * Changing the time of day in one domain does not affect the time of + * day on any other domain. + * + * Time is described by a single unsigned 64-bit word which is the + * number of seconds since the UNIX Epoch (00:00:00 UTC, January 1, + * 1970). + */ + +/* tod_get() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_TOD_GET + * RET0: status + * RET1: TOD + * ERRORS: EWOULDBLOCK TOD resource is temporarily unavailable + * ENOTSUPPORTED If TOD not supported on this platform + * + * Return the current time of day. May block if TOD access is + * temporarily not possible. + */ +#define HV_FAST_TOD_GET 0x50 + +/* tod_set() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_TOD_SET + * ARG0: TOD + * RET0: status + * ERRORS: EWOULDBLOCK TOD resource is temporarily unavailable + * ENOTSUPPORTED If TOD not supported on this platform + * + * The current time of day is set to the value specified in ARG0. May + * block if TOD access is temporarily not possible. + */ +#define HV_FAST_TOD_SET 0x51 + +/* Console services */ + +/* con_getchar() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_CONS_GETCHAR + * RET0: status + * RET1: character + * ERRORS: EWOULDBLOCK No character available. + * + * Returns a character from the console device. If no character is + * available then an EWOULDBLOCK error is returned. If a character is + * available, then the returned status is EOK and the character value + * is in RET1. + * + * A virtual BREAK is represented by the 64-bit value -1. + * + * A virtual HUP signal is represented by the 64-bit value -2. + */ +#define HV_FAST_CONS_GETCHAR 0x60 + +/* con_putchar() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_CONS_PUTCHAR + * ARG0: character + * RET0: status + * ERRORS: EINVAL Illegal character + * EWOULDBLOCK Output buffer currentl full, would block + * + * Send a character to the console device. Only character values + * between 0 and 255 may be used. Values outside this range are + * invalid except for the 64-bit value -1 which is used to send a + * virtual BREAK. + */ +#define HV_FAST_CONS_PUTCHAR 0x61 + +/* Trap trace services. + * + * The hypervisor provides a trap tracing capability for privileged + * code running on each virtual CPU. Privileged code provides a + * round-robin trap trace queue within which the hypervisor writes + * 64-byte entries detailing hyperprivileged traps taken n behalf of + * privileged code. This is provided as a debugging capability for + * privileged code. + * + * The trap trace control structure is 64-bytes long and placed at the + * start (offset 0) of the trap trace buffer, and is described as + * follows: + */ +#ifndef __ASSEMBLY__ +struct hv_trap_trace_control { + unsigned long head_offset; + unsigned long tail_offset; + unsigned long __reserved[0x30 / sizeof(unsigned long)]; +}; +#endif +#define HV_TRAP_TRACE_CTRL_HEAD_OFFSET 0x00 +#define HV_TRAP_TRACE_CTRL_TAIL_OFFSET 0x08 + +/* The head offset is the offset of the most recently completed entry + * in the trap-trace buffer. The tail offset is the offset of the + * next entry to be written. The control structure is owned and + * modified by the hypervisor. A guest may not modify the control + * structure contents. Attempts to do so will result in undefined + * behavior for the guest. + * + * Each trap trace buffer entry is layed out as follows: + */ +#ifndef __ASSEMBLY__ +struct hv_trap_trace_entry { + unsigned char type; /* Hypervisor or guest entry? */ + unsigned char hpstate; /* Hyper-privileged state */ + unsigned char tl; /* Trap level */ + unsigned char gl; /* Global register level */ + unsigned short tt; /* Trap type */ + unsigned short tag; /* Extended trap identifier */ + unsigned long tstate; /* Trap state */ + unsigned long tick; /* Tick */ + unsigned long tpc; /* Trap PC */ + unsigned long f1; /* Entry specific */ + unsigned long f2; /* Entry specific */ + unsigned long f3; /* Entry specific */ + unsigned long f4; /* Entry specific */ +}; +#endif +#define HV_TRAP_TRACE_ENTRY_TYPE 0x00 +#define HV_TRAP_TRACE_ENTRY_HPSTATE 0x01 +#define HV_TRAP_TRACE_ENTRY_TL 0x02 +#define HV_TRAP_TRACE_ENTRY_GL 0x03 +#define HV_TRAP_TRACE_ENTRY_TT 0x04 +#define HV_TRAP_TRACE_ENTRY_TAG 0x06 +#define HV_TRAP_TRACE_ENTRY_TSTATE 0x08 +#define HV_TRAP_TRACE_ENTRY_TICK 0x10 +#define HV_TRAP_TRACE_ENTRY_TPC 0x18 +#define HV_TRAP_TRACE_ENTRY_F1 0x20 +#define HV_TRAP_TRACE_ENTRY_F2 0x28 +#define HV_TRAP_TRACE_ENTRY_F3 0x30 +#define HV_TRAP_TRACE_ENTRY_F4 0x38 + +/* The type field is encoded as follows. */ +#define HV_TRAP_TYPE_UNDEF 0x00 /* Entry content undefined */ +#define HV_TRAP_TYPE_HV 0x01 /* Hypervisor trap entry */ +#define HV_TRAP_TYPE_GUEST 0xff /* Added via ttrace_addentry() */ + +/* ttrace_buf_conf() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_TTRACE_BUF_CONF + * ARG0: real address + * ARG1: number of entries + * RET0: status + * RET1: number of entries + * ERRORS: ENORADDR Invalid real address + * EINVAL Size is too small + * EBADALIGN Real address not aligned on 64-byte boundary + * + * Requests hypervisor trap tracing and declares a virtual CPU's trap + * trace buffer to the hypervisor. The real address supplies the real + * base address of the trap trace queue and must be 64-byte aligned. + * Specifying a value of 0 for the number of entries disables trap + * tracing for the calling virtual CPU. The buffer allocated must be + * sized for a power of two number of 64-byte trap trace entries plus + * an initial 64-byte control structure. + * + * This may be invoked any number of times so that a virtual CPU may + * relocate a trap trace buffer or create "snapshots" of information. + * + * If the real address is illegal or badly aligned, then trap tracing + * is disabled and an error is returned. + * + * Upon failure with EINVAL, this service call returns in RET1 the + * minimum number of buffer entries required. Upon other failures + * RET1 is undefined. + */ +#define HV_FAST_TTRACE_BUF_CONF 0x90 + +/* ttrace_buf_info() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_TTRACE_BUF_INFO + * RET0: status + * RET1: real address + * RET2: size + * ERRORS: None defined. + * + * Returns the size and location of the previously declared trap-trace + * buffer. In the event that no buffer was previously defined, or the + * buffer is disabled, this call will return a size of zero bytes. + */ +#define HV_FAST_TTRACE_BUF_INFO 0x91 + +/* ttrace_enable() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_TTRACE_ENABLE + * ARG0: enable + * RET0: status + * RET1: previous enable state + * ERRORS: EINVAL No trap trace buffer currently defined + * + * Enable or disable trap tracing, and return the previous enabled + * state in RET1. Future systems may define various flags for the + * enable argument (ARG0), for the moment a guest should pass + * "(uint64_t) -1" to enable, and "(uint64_t) 0" to disable all + * tracing - which will ensure future compatability. + */ +#define HV_FAST_TTRACE_ENABLE 0x92 + +/* ttrace_freeze() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_TTRACE_FREEZE + * ARG0: freeze + * RET0: status + * RET1: previous freeze state + * ERRORS: EINVAL No trap trace buffer currently defined + * + * Freeze or unfreeze trap tracing, returning the previous freeze + * state in RET1. A guest should pass a non-zero value to freeze and + * a zero value to unfreeze all tracing. The returned previous state + * is 0 for not frozen and 1 for frozen. + */ +#define HV_FAST_TTRACE_FREEZE 0x93 + +/* ttrace_addentry() + * TRAP: HV_TTRACE_ADDENTRY_TRAP + * ARG0: tag (16-bits) + * ARG1: data word 0 + * ARG2: data word 1 + * ARG3: data word 2 + * ARG4: data word 3 + * RET0: status + * ERRORS: EINVAL No trap trace buffer currently defined + * + * Add an entry to the trap trace buffer. Upon return only ARG0/RET0 + * is modified - none of the other registers holding arguments are + * volatile across this hypervisor service. + */ + +/* Core dump services. + * + * Since the hypervisor viraulizes and thus obscures a lot of the + * physical machine layout and state, traditional OS crash dumps can + * be difficult to diagnose especially when the problem is a + * configuration error of some sort. + * + * The dump services provide an opaque buffer into which the + * hypervisor can place it's internal state in order to assist in + * debugging such situations. The contents are opaque and extremely + * platform and hypervisor implementation specific. The guest, during + * a core dump, requests that the hypervisor update any information in + * the dump buffer in preparation to being dumped as part of the + * domain's memory image. + */ + +/* dump_buf_update() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_DUMP_BUF_UPDATE + * ARG0: real address + * ARG1: size + * RET0: status + * RET1: required size of dump buffer + * ERRORS: ENORADDR Invalid real address + * EBADALIGN Real address is not aligned on a 64-byte + * boundary + * EINVAL Size is non-zero but less than minimum size + * required + * ENOTSUPPORTED Operation not supported on current logical + * domain + * + * Declare a domain dump buffer to the hypervisor. The real address + * provided for the domain dump buffer must be 64-byte aligned. The + * size specifies the size of the dump buffer and may be larger than + * the minimum size specified in the machine description. The + * hypervisor will fill the dump buffer with opaque data. + * + * Note: A guest may elect to include dump buffer contents as part of a crash + * dump to assist with debugging. This function may be called any number + * of times so that a guest may relocate a dump buffer, or create + * "snapshots" of any dump-buffer information. Each call to + * dump_buf_update() atomically declares the new dump buffer to the + * hypervisor. + * + * A specified size of 0 unconfigures the dump buffer. If the real + * address is illegal or badly aligned, then any currently active dump + * buffer is disabled and an error is returned. + * + * In the event that the call fails with EINVAL, RET1 contains the + * minimum size requires by the hypervisor for a valid dump buffer. + */ +#define HV_FAST_DUMP_BUF_UPDATE 0x94 + +/* dump_buf_info() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_DUMP_BUF_INFO + * RET0: status + * RET1: real address of current dump buffer + * RET2: size of current dump buffer + * ERRORS: No errors defined. + * + * Return the currently configures dump buffer description. A + * returned size of 0 bytes indicates an undefined dump buffer. In + * this case the return address in RET1 is undefined. + */ +#define HV_FAST_DUMP_BUF_INFO 0x95 + +/* Device interrupt services. + * + * Device interrupts are allocated to system bus bridges by the hypervisor, + * and described to OBP in the machine description. OBP then describes + * these interrupts to the OS via properties in the device tree. + * + * Terminology: + * + * cpuid Unique opaque value which represents a target cpu. + * + * devhandle Device handle. It uniquely identifies a device, and + * consistes of the lower 28-bits of the hi-cell of the + * first entry of the device's "reg" property in the + * OBP device tree. + * + * devino Device interrupt number. Specifies the relative + * interrupt number within the device. The unique + * combination of devhandle and devino are used to + * identify a specific device interrupt. + * + * Note: The devino value is the same as the values in the + * "interrupts" property or "interrupt-map" property + * in the OBP device tree for that device. + * + * sysino System interrupt number. A 64-bit unsigned interger + * representing a unique interrupt within a virtual + * machine. + * + * intr_state A flag representing the interrupt state for a given + * sysino. The state values are defined below. + * + * intr_enabled A flag representing the 'enabled' state for a given + * sysino. The enable values are defined below. + */ + +#define HV_INTR_STATE_IDLE 0 /* Nothing pending */ +#define HV_INTR_STATE_RECEIVED 1 /* Interrupt received by hardware */ +#define HV_INTR_STATE_DELIVERED 2 /* Interrupt delivered to queue */ + +#define HV_INTR_DISABLED 0 /* sysino not enabled */ +#define HV_INTR_ENABLED 1 /* sysino enabled */ + +/* intr_devino_to_sysino() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_INTR_DEVINO2SYSINO + * ARG0: devhandle + * ARG1: devino + * RET0: status + * RET1: sysino + * ERRORS: EINVAL Invalid devhandle/devino + * + * Converts a device specific interrupt number of the given + * devhandle/devino into a system specific ino (sysino). + */ +#define HV_FAST_INTR_DEVINO2SYSINO 0xa0 + +/* intr_getenabled() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_INTR_GETENABLED + * ARG0: sysino + * RET0: status + * RET1: intr_enabled (HV_INTR_{DISABLED,ENABLED}) + * ERRORS: EINVAL Invalid sysino + * + * Returns interrupt enabled state in RET1 for the interrupt defined + * by the given sysino. + */ +#define HV_FAST_INTR_GETENABLED 0xa1 + +/* intr_setenabled() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_INTR_SETENABLED + * ARG0: sysino + * ARG1: intr_enabled (HV_INTR_{DISABLED,ENABLED}) + * RET0: status + * ERRORS: EINVAL Invalid sysino or intr_enabled value + * + * Set the 'enabled' state of the interrupt sysino. + */ +#define HV_FAST_INTR_SETENABLED 0xa2 + +/* intr_getstate() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_INTR_GETSTATE + * ARG0: sysino + * RET0: status + * RET1: intr_state (HV_INTR_STATE_*) + * ERRORS: EINVAL Invalid sysino + * + * Returns current state of the interrupt defined by the given sysino. + */ +#define HV_FAST_INTR_GETSTATE 0xa3 + +/* intr_setstate() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_INTR_SETSTATE + * ARG0: sysino + * ARG1: intr_state (HV_INTR_STATE_*) + * RET0: status + * ERRORS: EINVAL Invalid sysino or intr_state value + * + * Sets the current state of the interrupt described by the given sysino + * value. + * + * Note: Setting the state to HV_INTR_STATE_IDLE clears any pending + * interrupt for sysino. + */ +#define HV_FAST_INTR_SETSTATE 0xa4 + +/* intr_gettarget() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_INTR_GETTARGET + * ARG0: sysino + * RET0: status + * RET1: cpuid + * ERRORS: EINVAL Invalid sysino + * + * Returns CPU that is the current target of the interrupt defined by + * the given sysino. The CPU value returned is undefined if the target + * has not been set via intr_settarget(). + */ +#define HV_FAST_INTR_GETTARGET 0xa5 + +/* intr_settarget() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_INTR_SETTARGET + * ARG0: sysino + * ARG1: cpuid + * RET0: status + * ERRORS: EINVAL Invalid sysino + * ENOCPU Invalid cpuid + * + * Set the target CPU for the interrupt defined by the given sysino. + */ +#define HV_FAST_INTR_SETTARGET 0xa6 + +/* PCI IO services. + * + * See the terminology descriptions in the device interrupt services + * section above as those apply here too. Here are terminology + * definitions specific to these PCI IO services: + * + * tsbnum TSB number. Indentifies which io-tsb is used. + * For this version of the specification, tsbnum + * must be zero. + * + * tsbindex TSB index. Identifies which entry in the TSB + * is used. The first entry is zero. + * + * tsbid A 64-bit aligned data structure which contains + * a tsbnum and a tsbindex. Bits 63:32 contain the + * tsbnum and bits 31:00 contain the tsbindex. + * + * io_attributes IO attributes for IOMMU mappings. One of more + * of the attritbute bits are stores in a 64-bit + * value. The values are defined below. + * + * r_addr 64-bit real address + * + * pci_device PCI device address. A PCI device address identifies + * a specific device on a specific PCI bus segment. + * A PCI device address ia a 32-bit unsigned integer + * with the following format: + * + * 00000000.bbbbbbbb.dddddfff.00000000 + * + * Use the HV_PCI_DEVICE_BUILD() macro to construct + * such values. + * + * pci_config_offset + * PCI configureation space offset. For conventional + * PCI a value between 0 and 255. For extended + * configuration space, a value between 0 and 4095. + * + * Note: For PCI configuration space accesses, the offset + * must be aligned to the access size. + * + * error_flag A return value which specifies if the action succeeded + * or failed. 0 means no error, non-0 means some error + * occurred while performing the service. + * + * io_sync_direction + * Direction definition for pci_dma_sync(), defined + * below in HV_PCI_SYNC_*. + * + * io_page_list A list of io_page_addresses, an io_page_address is + * a real address. + * + * io_page_list_p A pointer to an io_page_list. + * + * "size based byte swap" - Some functions do size based byte swapping + * which allows sw to access pointers and + * counters in native form when the processor + * operates in a different endianness than the + * IO bus. Size-based byte swapping converts a + * multi-byte field between big-endian and + * little-endian format. + */ + +#define HV_PCI_MAP_ATTR_READ 0x01 +#define HV_PCI_MAP_ATTR_WRITE 0x02 + +#define HV_PCI_DEVICE_BUILD(b,d,f) \ + ((((b) & 0xff) << 16) | \ + (((d) & 0x1f) << 11) | \ + (((f) & 0x07) << 8)) + +#define HV_PCI_SYNC_FOR_DEVICE 0x01 +#define HV_PCI_SYNC_FOR_CPU 0x02 + +/* pci_iommu_map() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_PCI_IOMMU_MAP + * ARG0: devhandle + * ARG1: tsbid + * ARG2: #ttes + * ARG3: io_attributes + * ARG4: io_page_list_p + * RET0: status + * RET1: #ttes mapped + * ERRORS: EINVAL Invalid devhandle/tsbnum/tsbindex/io_attributes + * EBADALIGN Improperly aligned real address + * ENORADDR Invalid real address + * + * Create IOMMU mappings in the sun4v device defined by the given + * devhandle. The mappings are created in the TSB defined by the + * tsbnum component of the given tsbid. The first mapping is created + * in the TSB i ndex defined by the tsbindex component of the given tsbid. + * The call creates up to #ttes mappings, the first one at tsbnum, tsbindex, + * the second at tsbnum, tsbindex + 1, etc. + * + * All mappings are created with the attributes defined by the io_attributes + * argument. The page mapping addresses are described in the io_page_list + * defined by the given io_page_list_p, which is a pointer to the io_page_list. + * The first entry in the io_page_list is the address for the first iotte, the + * 2nd for the 2nd iotte, and so on. + * + * Each io_page_address in the io_page_list must be appropriately aligned. + * #ttes must be greater than zero. For this version of the spec, the tsbnum + * component of the given tsbid must be zero. + * + * Returns the actual number of mappings creates, which may be less than + * or equal to the argument #ttes. If the function returns a value which + * is less than the #ttes, the caller may continus to call the function with + * an updated tsbid, #ttes, io_page_list_p arguments until all pages are + * mapped. + * + * Note: This function does not imply an iotte cache flush. The guest must + * demap an entry before re-mapping it. + */ +#define HV_FAST_PCI_IOMMU_MAP 0xb0 + +/* pci_iommu_demap() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_PCI_IOMMU_DEMAP + * ARG0: devhandle + * ARG1: tsbid + * ARG2: #ttes + * RET0: status + * RET1: #ttes demapped + * ERRORS: EINVAL Invalid devhandle/tsbnum/tsbindex + * + * Demap and flush IOMMU mappings in the device defined by the given + * devhandle. Demaps up to #ttes entries in the TSB defined by the tsbnum + * component of the given tsbid, starting at the TSB index defined by the + * tsbindex component of the given tsbid. + * + * For this version of the spec, the tsbnum of the given tsbid must be zero. + * #ttes must be greater than zero. + * + * Returns the actual number of ttes demapped, which may be less than or equal + * to the argument #ttes. If #ttes demapped is less than #ttes, the caller + * may continue to call this function with updated tsbid and #ttes arguments + * until all pages are demapped. + * + * Note: Entries do not have to be mapped to be demapped. A demap of an + * unmapped page will flush the entry from the tte cache. + */ +#define HV_FAST_PCI_IOMMU_DEMAP 0xb1 + +/* pci_iommu_getmap() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_PCI_IOMMU_GETMAP + * ARG0: devhandle + * ARG1: tsbid + * RET0: status + * RET1: io_attributes + * RET2: real address + * ERRORS: EINVAL Invalid devhandle/tsbnum/tsbindex + * ENOMAP Mapping is not valid, no translation exists + * + * Read and return the mapping in the device described by the given devhandle + * and tsbid. If successful, the io_attributes shall be returned in RET1 + * and the page address of the mapping shall be returned in RET2. + * + * For this version of the spec, the tsbnum component of the given tsbid + * must be zero. + */ +#define HV_FAST_PCI_IOMMU_GETMAP 0xb2 + +/* pci_iommu_getbypass() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_PCI_IOMMU_GETBYPASS + * ARG0: devhandle + * ARG1: real address + * ARG2: io_attributes + * RET0: status + * RET1: io_addr + * ERRORS: EINVAL Invalid devhandle/io_attributes + * ENORADDR Invalid real address + * ENOTSUPPORTED Function not supported in this implementation. + * + * Create a "special" mapping in the device described by the given devhandle, + * for the given real address and attributes. Return the IO address in RET1 + * if successful. + */ +#define HV_FAST_PCI_IOMMU_GETBYPASS 0xb3 + +/* pci_config_get() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_PCI_CONFIG_GET + * ARG0: devhandle + * ARG1: pci_device + * ARG2: pci_config_offset + * ARG3: size + * RET0: status + * RET1: error_flag + * RET2: data + * ERRORS: EINVAL Invalid devhandle/pci_device/offset/size + * EBADALIGN pci_config_offset not size aligned + * ENOACCESS Access to this offset is not permitted + * + * Read PCI configuration space for the adapter described by the given + * devhandle. Read size (1, 2, or 4) bytes of data from the given + * pci_device, at pci_config_offset from the beginning of the device's + * configuration space. If there was no error, RET1 is set to zero and + * RET2 is set to the data read. Insignificant bits in RET2 are not + * guarenteed to have any specific value and therefore must be ignored. + * + * The data returned in RET2 is size based byte swapped. + * + * If an error occurs during the read, set RET1 to a non-zero value. The + * given pci_config_offset must be 'size' aligned. + */ +#define HV_FAST_PCI_CONFIG_GET 0xb4 + +/* pci_config_put() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_PCI_CONFIG_PUT + * ARG0: devhandle + * ARG1: pci_device + * ARG2: pci_config_offset + * ARG3: size + * ARG4: data + * RET0: status + * RET1: error_flag + * ERRORS: EINVAL Invalid devhandle/pci_device/offset/size + * EBADALIGN pci_config_offset not size aligned + * ENOACCESS Access to this offset is not permitted + * + * Write PCI configuration space for the adapter described by the given + * devhandle. Write size (1, 2, or 4) bytes of data in a single operation, + * at pci_config_offset from the beginning of the device's configuration + * space. The data argument contains the data to be written to configuration + * space. Prior to writing, the data is size based byte swapped. + * + * If an error occurs during the write access, do not generate an error + * report, do set RET1 to a non-zero value. Otherwise RET1 is zero. + * The given pci_config_offset must be 'size' aligned. + * + * This function is permitted to read from offset zero in the configuration + * space described by the given pci_device if necessary to ensure that the + * write access to config space completes. + */ +#define HV_FAST_PCI_CONFIG_PUT 0xb5 + +/* pci_peek() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_PCI_PEEK + * ARG0: devhandle + * ARG1: real address + * ARG2: size + * RET0: status + * RET1: error_flag + * RET2: data + * ERRORS: EINVAL Invalid devhandle or size + * EBADALIGN Improperly aligned real address + * ENORADDR Bad real address + * ENOACCESS Guest access prohibited + * + * Attempt to read the IO address given by the given devhandle, real address, + * and size. Size must be 1, 2, 4, or 8. The read is performed as a single + * access operation using the given size. If an error occurs when reading + * from the given location, do not generate an error report, but return a + * non-zero value in RET1. If the read was successful, return zero in RET1 + * and return the actual data read in RET2. The data returned is size based + * byte swapped. + * + * Non-significant bits in RET2 are not guarenteed to have any specific value + * and therefore must be ignored. If RET1 is returned as non-zero, the data + * value is not guarenteed to have any specific value and should be ignored. + * + * The caller must have permission to read from the given devhandle, real + * address, which must be an IO address. The argument real address must be a + * size aligned address. + * + * The hypervisor implementation of this function must block access to any + * IO address that the guest does not have explicit permission to access. + */ +#define HV_FAST_PCI_PEEK 0xb6 + +/* pci_poke() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_PCI_POKE + * ARG0: devhandle + * ARG1: real address + * ARG2: size + * ARG3: data + * ARG4: pci_device + * RET0: status + * RET1: error_flag + * ERRORS: EINVAL Invalid devhandle, size, or pci_device + * EBADALIGN Improperly aligned real address + * ENORADDR Bad real address + * ENOACCESS Guest access prohibited + * ENOTSUPPORTED Function is not supported by implementation + * + * Attempt to write data to the IO address given by the given devhandle, + * real address, and size. Size must be 1, 2, 4, or 8. The write is + * performed as a single access operation using the given size. Prior to + * writing the data is size based swapped. + * + * If an error occurs when writing to the given location, do not generate an + * error report, but return a non-zero value in RET1. If the write was + * successful, return zero in RET1. + * + * pci_device describes the configuration address of the device being + * written to. The implementation may safely read from offset 0 with + * the configuration space of the device described by devhandle and + * pci_device in order to guarantee that the write portion of the operation + * completes + * + * Any error that occurs due to the read shall be reported using the normal + * error reporting mechanisms .. the read error is not suppressed. + * + * The caller must have permission to write to the given devhandle, real + * address, which must be an IO address. The argument real address must be a + * size aligned address. The caller must have permission to read from + * the given devhandle, pci_device cofiguration space offset 0. + * + * The hypervisor implementation of this function must block access to any + * IO address that the guest does not have explicit permission to access. + */ +#define HV_FAST_PCI_POKE 0xb7 + +/* pci_dma_sync() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_PCI_DMA_SYNC + * ARG0: devhandle + * ARG1: real address + * ARG2: size + * ARG3: io_sync_direction + * RET0: status + * RET1: #synced + * ERRORS: EINVAL Invalid devhandle or io_sync_direction + * ENORADDR Bad real address + * + * Synchronize a memory region described by the given real address and size, + * for the device defined by the given devhandle using the direction(s) + * defined by the given io_sync_direction. The argument size is the size of + * the memory region in bytes. + * + * Return the actual number of bytes synchronized in the return value #synced, + * which may be less than or equal to the argument size. If the return + * value #synced is less than size, the caller must continue to call this + * function with updated real address and size arguments until the entire + * memory region is synchronized. + */ +#define HV_FAST_PCI_DMA_SYNC 0xb8 + +/* PCI MSI services. */ + +#define HV_MSITYPE_MSI32 0x00 +#define HV_MSITYPE_MSI64 0x01 + +#define HV_MSIQSTATE_IDLE 0x00 +#define HV_MSIQSTATE_ERROR 0x01 + +#define HV_MSIQ_INVALID 0x00 +#define HV_MSIQ_VALID 0x01 + +#define HV_MSISTATE_IDLE 0x00 +#define HV_MSISTATE_DELIVERED 0x01 + +#define HV_MSIVALID_INVALID 0x00 +#define HV_MSIVALID_VALID 0x01 + +#define HV_PCIE_MSGTYPE_PME_MSG 0x18 +#define HV_PCIE_MSGTYPE_PME_ACK_MSG 0x1b +#define HV_PCIE_MSGTYPE_CORR_MSG 0x30 +#define HV_PCIE_MSGTYPE_NONFATAL_MSG 0x31 +#define HV_PCIE_MSGTYPE_FATAL_MSG 0x33 + +#define HV_MSG_INVALID 0x00 +#define HV_MSG_VALID 0x01 + +/* pci_msiq_conf() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_PCI_MSIQ_CONF + * ARG0: devhandle + * ARG1: msiqid + * ARG2: real address + * ARG3: number of entries + * RET0: status + * ERRORS: EINVAL Invalid devhandle, msiqid or nentries + * EBADALIGN Improperly aligned real address + * ENORADDR Bad real address + * + * Configure the MSI queue given by the devhandle and msiqid arguments, + * and to be placed at the given real address and be of the given + * number of entries. The real address must be aligned exactly to match + * the queue size. Each queue entry is 64-bytes long, so f.e. a 32 entry + * queue must be aligned on a 2048 byte real address boundary. The MSI-EQ + * Head and Tail are initialized so that the MSI-EQ is 'empty'. + * + * Implementation Note: Certain implementations have fixed sized queues. In + * that case, number of entries must contain the correct + * value. + */ +#define HV_FAST_PCI_MSIQ_CONF 0xc0 + +/* pci_msiq_info() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_PCI_MSIQ_INFO + * ARG0: devhandle + * ARG1: msiqid + * RET0: status + * RET1: real address + * RET2: number of entries + * ERRORS: EINVAL Invalid devhandle or msiqid + * + * Return the configuration information for the MSI queue described + * by the given devhandle and msiqid. The base address of the queue + * is returned in ARG1 and the number of entries is returned in ARG2. + * If the queue is unconfigured, the real address is undefined and the + * number of entries will be returned as zero. + */ +#define HV_FAST_PCI_MSIQ_INFO 0xc1 + +/* pci_msiq_getvalid() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_PCI_MSIQ_GETVALID + * ARG0: devhandle + * ARG1: msiqid + * RET0: status + * RET1: msiqvalid (HV_MSIQ_VALID or HV_MSIQ_INVALID) + * ERRORS: EINVAL Invalid devhandle or msiqid + * + * Get the valid state of the MSI-EQ described by the given devhandle and + * msiqid. + */ +#define HV_FAST_PCI_MSIQ_GETVALID 0xc2 + +/* pci_msiq_setvalid() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_PCI_MSIQ_SETVALID + * ARG0: devhandle + * ARG1: msiqid + * ARG2: msiqvalid (HV_MSIQ_VALID or HV_MSIQ_INVALID) + * RET0: status + * ERRORS: EINVAL Invalid devhandle or msiqid or msiqvalid + * value or MSI EQ is uninitialized + * + * Set the valid state of the MSI-EQ described by the given devhandle and + * msiqid to the given msiqvalid. + */ +#define HV_FAST_PCI_MSIQ_SETVALID 0xc3 + +/* pci_msiq_getstate() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_PCI_MSIQ_GETSTATE + * ARG0: devhandle + * ARG1: msiqid + * RET0: status + * RET1: msiqstate (HV_MSIQSTATE_IDLE or HV_MSIQSTATE_ERROR) + * ERRORS: EINVAL Invalid devhandle or msiqid + * + * Get the state of the MSI-EQ described by the given devhandle and + * msiqid. + */ +#define HV_FAST_PCI_MSIQ_GETSTATE 0xc4 + +/* pci_msiq_getvalid() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_PCI_MSIQ_GETVALID + * ARG0: devhandle + * ARG1: msiqid + * ARG2: msiqstate (HV_MSIQSTATE_IDLE or HV_MSIQSTATE_ERROR) + * RET0: status + * ERRORS: EINVAL Invalid devhandle or msiqid or msiqstate + * value or MSI EQ is uninitialized + * + * Set the state of the MSI-EQ described by the given devhandle and + * msiqid to the given msiqvalid. + */ +#define HV_FAST_PCI_MSIQ_SETSTATE 0xc5 + +/* pci_msiq_gethead() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_PCI_MSIQ_GETHEAD + * ARG0: devhandle + * ARG1: msiqid + * RET0: status + * RET1: msiqhead + * ERRORS: EINVAL Invalid devhandle or msiqid + * + * Get the current MSI EQ queue head for the MSI-EQ described by the + * given devhandle and msiqid. + */ +#define HV_FAST_PCI_MSIQ_GETHEAD 0xc6 + +/* pci_msiq_sethead() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_PCI_MSIQ_SETHEAD + * ARG0: devhandle + * ARG1: msiqid + * ARG2: msiqhead + * RET0: status + * ERRORS: EINVAL Invalid devhandle or msiqid or msiqhead, + * or MSI EQ is uninitialized + * + * Set the current MSI EQ queue head for the MSI-EQ described by the + * given devhandle and msiqid. + */ +#define HV_FAST_PCI_MSIQ_SETHEAD 0xc7 + +/* pci_msiq_gettail() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_PCI_MSIQ_GETTAIL + * ARG0: devhandle + * ARG1: msiqid + * RET0: status + * RET1: msiqtail + * ERRORS: EINVAL Invalid devhandle or msiqid + * + * Get the current MSI EQ queue tail for the MSI-EQ described by the + * given devhandle and msiqid. + */ +#define HV_FAST_PCI_MSIQ_GETTAIL 0xc8 + +/* pci_msi_getvalid() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_PCI_MSI_GETVALID + * ARG0: devhandle + * ARG1: msinum + * RET0: status + * RET1: msivalidstate + * ERRORS: EINVAL Invalid devhandle or msinum + * + * Get the current valid/enabled state for the MSI defined by the + * given devhandle and msinum. + */ +#define HV_FAST_PCI_MSI_GETVALID 0xc9 + +/* pci_msi_setvalid() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_PCI_MSI_SETVALID + * ARG0: devhandle + * ARG1: msinum + * ARG2: msivalidstate + * RET0: status + * ERRORS: EINVAL Invalid devhandle or msinum or msivalidstate + * + * Set the current valid/enabled state for the MSI defined by the + * given devhandle and msinum. + */ +#define HV_FAST_PCI_MSI_SETVALID 0xca + +/* pci_msi_getmsiq() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_PCI_MSI_GETMSIQ + * ARG0: devhandle + * ARG1: msinum + * RET0: status + * RET1: msiqid + * ERRORS: EINVAL Invalid devhandle or msinum or MSI is unbound + * + * Get the MSI EQ that the MSI defined by the given devhandle and + * msinum is bound to. + */ +#define HV_FAST_PCI_MSI_GETMSIQ 0xcb + +/* pci_msi_setmsiq() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_PCI_MSI_SETMSIQ + * ARG0: devhandle + * ARG1: msinum + * ARG2: msitype + * ARG3: msiqid + * RET0: status + * ERRORS: EINVAL Invalid devhandle or msinum or msiqid + * + * Set the MSI EQ that the MSI defined by the given devhandle and + * msinum is bound to. + */ +#define HV_FAST_PCI_MSI_SETMSIQ 0xcc + +/* pci_msi_getstate() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_PCI_MSI_GETSTATE + * ARG0: devhandle + * ARG1: msinum + * RET0: status + * RET1: msistate + * ERRORS: EINVAL Invalid devhandle or msinum + * + * Get the state of the MSI defined by the given devhandle and msinum. + * If not initialized, return HV_MSISTATE_IDLE. + */ +#define HV_FAST_PCI_MSI_GETSTATE 0xcd + +/* pci_msi_setstate() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_PCI_MSI_SETSTATE + * ARG0: devhandle + * ARG1: msinum + * ARG2: msistate + * RET0: status + * ERRORS: EINVAL Invalid devhandle or msinum or msistate + * + * Set the state of the MSI defined by the given devhandle and msinum. + */ +#define HV_FAST_PCI_MSI_SETSTATE 0xce + +/* pci_msg_getmsiq() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_PCI_MSG_GETMSIQ + * ARG0: devhandle + * ARG1: msgtype + * RET0: status + * RET1: msiqid + * ERRORS: EINVAL Invalid devhandle or msgtype + * + * Get the MSI EQ of the MSG defined by the given devhandle and msgtype. + */ +#define HV_FAST_PCI_MSG_GETMSIQ 0xd0 + +/* pci_msg_setmsiq() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_PCI_MSG_SETMSIQ + * ARG0: devhandle + * ARG1: msgtype + * ARG2: msiqid + * RET0: status + * ERRORS: EINVAL Invalid devhandle, msgtype, or msiqid + * + * Set the MSI EQ of the MSG defined by the given devhandle and msgtype. + */ +#define HV_FAST_PCI_MSG_SETMSIQ 0xd1 + +/* pci_msg_getvalid() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_PCI_MSG_GETVALID + * ARG0: devhandle + * ARG1: msgtype + * RET0: status + * RET1: msgvalidstate + * ERRORS: EINVAL Invalid devhandle or msgtype + * + * Get the valid/enabled state of the MSG defined by the given + * devhandle and msgtype. + */ +#define HV_FAST_PCI_MSG_GETVALID 0xd2 + +/* pci_msg_setvalid() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_PCI_MSG_SETVALID + * ARG0: devhandle + * ARG1: msgtype + * ARG2: msgvalidstate + * RET0: status + * ERRORS: EINVAL Invalid devhandle or msgtype or msgvalidstate + * + * Set the valid/enabled state of the MSG defined by the given + * devhandle and msgtype. + */ +#define HV_FAST_PCI_MSG_SETVALID 0xd3 + +/* Performance counter services. */ + +#define HV_PERF_JBUS_PERF_CTRL_REG 0x00 +#define HV_PERF_JBUS_PERF_CNT_REG 0x01 +#define HV_PERF_DRAM_PERF_CTRL_REG_0 0x02 +#define HV_PERF_DRAM_PERF_CNT_REG_0 0x03 +#define HV_PERF_DRAM_PERF_CTRL_REG_1 0x04 +#define HV_PERF_DRAM_PERF_CNT_REG_1 0x05 +#define HV_PERF_DRAM_PERF_CTRL_REG_2 0x06 +#define HV_PERF_DRAM_PERF_CNT_REG_2 0x07 +#define HV_PERF_DRAM_PERF_CTRL_REG_3 0x08 +#define HV_PERF_DRAM_PERF_CNT_REG_3 0x09 + +/* get_perfreg() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_GET_PERFREG + * ARG0: performance reg number + * RET0: status + * RET1: performance reg value + * ERRORS: EINVAL Invalid performance register number + * ENOACCESS No access allowed to performance counters + * + * Read the value of the given DRAM/JBUS performance counter/control register. + */ +#define HV_FAST_GET_PERFREG 0x100 + +/* set_perfreg() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_SET_PERFREG + * ARG0: performance reg number + * ARG1: performance reg value + * RET0: status + * ERRORS: EINVAL Invalid performance register number + * ENOACCESS No access allowed to performance counters + * + * Write the given performance reg value to the given DRAM/JBUS + * performance counter/control register. + */ +#define HV_FAST_SET_PERFREG 0x101 + +/* MMU statistics services. + * + * The hypervisor maintains MMU statistics and privileged code provides + * a buffer where these statistics can be collected. It is continually + * updated once configured. The layout is as follows: + */ +#ifndef __ASSEMBLY__ +struct hv_mmu_statistics { + unsigned long immu_tsb_hits_ctx0_8k_tte; + unsigned long immu_tsb_ticks_ctx0_8k_tte; + unsigned long immu_tsb_hits_ctx0_64k_tte; + unsigned long immu_tsb_ticks_ctx0_64k_tte; + unsigned long __reserved1[2]; + unsigned long immu_tsb_hits_ctx0_4mb_tte; + unsigned long immu_tsb_ticks_ctx0_4mb_tte; + unsigned long __reserved2[2]; + unsigned long immu_tsb_hits_ctx0_256mb_tte; + unsigned long immu_tsb_ticks_ctx0_256mb_tte; + unsigned long __reserved3[4]; + unsigned long immu_tsb_hits_ctxnon0_8k_tte; + unsigned long immu_tsb_ticks_ctxnon0_8k_tte; + unsigned long immu_tsb_hits_ctxnon0_64k_tte; + unsigned long immu_tsb_ticks_ctxnon0_64k_tte; + unsigned long __reserved4[2]; + unsigned long immu_tsb_hits_ctxnon0_4mb_tte; + unsigned long immu_tsb_ticks_ctxnon0_4mb_tte; + unsigned long __reserved5[2]; + unsigned long immu_tsb_hits_ctxnon0_256mb_tte; + unsigned long immu_tsb_ticks_ctxnon0_256mb_tte; + unsigned long __reserved6[4]; + unsigned long dmmu_tsb_hits_ctx0_8k_tte; + unsigned long dmmu_tsb_ticks_ctx0_8k_tte; + unsigned long dmmu_tsb_hits_ctx0_64k_tte; + unsigned long dmmu_tsb_ticks_ctx0_64k_tte; + unsigned long __reserved7[2]; + unsigned long dmmu_tsb_hits_ctx0_4mb_tte; + unsigned long dmmu_tsb_ticks_ctx0_4mb_tte; + unsigned long __reserved8[2]; + unsigned long dmmu_tsb_hits_ctx0_256mb_tte; + unsigned long dmmu_tsb_ticks_ctx0_256mb_tte; + unsigned long __reserved9[4]; + unsigned long dmmu_tsb_hits_ctxnon0_8k_tte; + unsigned long dmmu_tsb_ticks_ctxnon0_8k_tte; + unsigned long dmmu_tsb_hits_ctxnon0_64k_tte; + unsigned long dmmu_tsb_ticks_ctxnon0_64k_tte; + unsigned long __reserved10[2]; + unsigned long dmmu_tsb_hits_ctxnon0_4mb_tte; + unsigned long dmmu_tsb_ticks_ctxnon0_4mb_tte; + unsigned long __reserved11[2]; + unsigned long dmmu_tsb_hits_ctxnon0_256mb_tte; + unsigned long dmmu_tsb_ticks_ctxnon0_256mb_tte; + unsigned long __reserved12[4]; +}; +#endif + +/* mmustat_conf() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_MMUSTAT_CONF + * ARG0: real address + * RET0: status + * RET1: real address + * ERRORS: ENORADDR Invalid real address + * EBADALIGN Real address not aligned on 64-byte boundary + * EBADTRAP API not supported on this processor + * + * Enable MMU statistic gathering using the buffer at the given real + * address on the current virtual CPU. The new buffer real address + * is given in ARG1, and the previously specified buffer real address + * is returned in RET1, or is returned as zero for the first invocation. + * + * If the passed in real address argument is zero, this will disable + * MMU statistic collection on the current virtual CPU. If an error is + * returned then no statistics are collected. + * + * The buffer contents should be initialized to all zeros before being + * given to the hypervisor or else the statistics will be meaningless. + */ +#define HV_FAST_MMUSTAT_CONF 0x102 + +/* mmustat_info() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_MMUSTAT_INFO + * RET0: status + * RET1: real address + * ERRORS: EBADTRAP API not supported on this processor + * + * Return the current state and real address of the currently configured + * MMU statistics buffer on the current virtual CPU. + */ +#define HV_FAST_MMUSTAT_INFO 0x103 + +/* Function numbers for HV_CORE_TRAP. */ +#define HV_CORE_VER 0x00 +#define HV_CORE_PUTCHAR 0x01 +#define HV_CORE_EXIT 0x02 + +#endif /* !(_SPARC64_HYPERVISOR_H) */ -- cgit v1.2.2 From 1633a53c79498455b16d051451f4e3f83ab4e7dd Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sat, 4 Feb 2006 03:09:03 -0800 Subject: [SPARC64]: Add 'hypervisor' to ultra_tlb_type enumeration. Signed-off-by: David S. Miller --- include/asm-sparc64/spitfire.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/asm-sparc64/spitfire.h b/include/asm-sparc64/spitfire.h index 962638c9d1..23ad8a7987 100644 --- a/include/asm-sparc64/spitfire.h +++ b/include/asm-sparc64/spitfire.h @@ -44,6 +44,7 @@ enum ultra_tlb_layout { spitfire = 0, cheetah = 1, cheetah_plus = 2, + hypervisor = 3, }; extern enum ultra_tlb_layout tlb_type; -- cgit v1.2.2 From 30ddbdb03339fc62480ddbff800a44066bb14455 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sat, 4 Feb 2006 03:11:17 -0800 Subject: [SPARC64]: Add Niagara init-store twin-load ASI defines. Signed-off-by: David S. Miller --- include/asm-sparc64/asi.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/asm-sparc64/asi.h b/include/asm-sparc64/asi.h index 534855660f..4b36f5f4c8 100644 --- a/include/asm-sparc64/asi.h +++ b/include/asm-sparc64/asi.h @@ -25,12 +25,16 @@ /* SpitFire and later extended ASIs. The "(III)" marker designates * UltraSparc-III and later specific ASIs. The "(CMT)" marker designates - * Chip Multi Threading specific ASIs. + * Chip Multi Threading specific ASIs. "(NG)" designates Niagara specific + * ASIs, "(4V)" designates SUN4V specific ASIs. */ #define ASI_PHYS_USE_EC 0x14 /* PADDR, E-cachable */ #define ASI_PHYS_BYPASS_EC_E 0x15 /* PADDR, E-bit */ #define ASI_PHYS_USE_EC_L 0x1c /* PADDR, E-cachable, little endian*/ #define ASI_PHYS_BYPASS_EC_E_L 0x1d /* PADDR, E-bit, little endian */ +#define ASI_BLK_INIT_QUAD_LDD_AIUS 0x23 /* (NG) init-store, twin load, + * secondary, user + */ #define ASI_NUCLEUS_QUAD_LDD 0x24 /* Cachable, qword load */ #define ASI_NUCLEUS_QUAD_LDD_L 0x2c /* Cachable, qword load, l-endian */ #define ASI_PCACHE_DATA_STATUS 0x30 /* (III) PCache data stat RAM diag */ @@ -137,6 +141,9 @@ #define ASI_FL16_SL 0xdb /* Secondary, 1 16-bit, fpu ld/st,L*/ #define ASI_BLK_COMMIT_P 0xe0 /* Primary, blk store commit */ #define ASI_BLK_COMMIT_S 0xe1 /* Secondary, blk store commit */ +#define ASI_BLK_INIT_QUAD_LDD_P 0xe2 /* (NG) init-store, twin load, + * primary, implicit + */ #define ASI_BLK_P 0xf0 /* Primary, blk ld/st */ #define ASI_BLK_S 0xf1 /* Secondary, blk ld/st */ #define ASI_BLK_PL 0xf8 /* Primary, blk ld/st, little */ -- cgit v1.2.2 From d398ee230f94a8ba386d8abb63f4fea129e4eaba Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sat, 4 Feb 2006 03:11:50 -0800 Subject: [SPARC64]: Sun4v specific ASI defines. Signed-off-by: David S. Miller --- include/asm-sparc64/asi.h | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'include') diff --git a/include/asm-sparc64/asi.h b/include/asm-sparc64/asi.h index 4b36f5f4c8..662a21107a 100644 --- a/include/asm-sparc64/asi.h +++ b/include/asm-sparc64/asi.h @@ -30,13 +30,22 @@ */ #define ASI_PHYS_USE_EC 0x14 /* PADDR, E-cachable */ #define ASI_PHYS_BYPASS_EC_E 0x15 /* PADDR, E-bit */ +#define ASI_BLK_AIUP_4V 0x16 /* (4V) Prim, user, block ld/st */ +#define ASI_BLK_AIUS_4V 0x17 /* (4V) Sec, user, block ld/st */ #define ASI_PHYS_USE_EC_L 0x1c /* PADDR, E-cachable, little endian*/ #define ASI_PHYS_BYPASS_EC_E_L 0x1d /* PADDR, E-bit, little endian */ +#define ASI_BLK_AIUP_L_4V 0x1e /* (4V) Prim, user, block, l-endian*/ +#define ASI_BLK_AIUS_L_4V 0x1f /* (4V) Sec, user, block, l-endian */ +#define ASI_SCRATCHPAD 0x20 /* (4V) Scratch Pad Registers */ +#define ASI_MMU 0x21 /* (4V) MMU Context Registers */ #define ASI_BLK_INIT_QUAD_LDD_AIUS 0x23 /* (NG) init-store, twin load, * secondary, user */ #define ASI_NUCLEUS_QUAD_LDD 0x24 /* Cachable, qword load */ +#define ASI_QUEUE 0x25 /* (4V) Interrupt Queue Registers */ +#define ASI_QUAD_LDD_PHYS_4V 0x26 /* (4V) Physical, qword load */ #define ASI_NUCLEUS_QUAD_LDD_L 0x2c /* Cachable, qword load, l-endian */ +#define ASI_QUAD_LDD_PHYS_L_4V 0x2e /* (4V) Phys, qword load, l-endian */ #define ASI_PCACHE_DATA_STATUS 0x30 /* (III) PCache data stat RAM diag */ #define ASI_PCACHE_DATA 0x31 /* (III) PCache data RAM diag */ #define ASI_PCACHE_TAG 0x32 /* (III) PCache tag RAM diag */ -- cgit v1.2.2 From 277b6dd9600613b01f66cadef2f0065514fecf69 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sat, 4 Feb 2006 03:12:02 -0800 Subject: [SPARC64]: Sun4v scratchpad register layout. Signed-off-by: David S. Miller --- include/asm-sparc64/scratchpad.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 include/asm-sparc64/scratchpad.h (limited to 'include') diff --git a/include/asm-sparc64/scratchpad.h b/include/asm-sparc64/scratchpad.h new file mode 100644 index 0000000000..5e8b01fb33 --- /dev/null +++ b/include/asm-sparc64/scratchpad.h @@ -0,0 +1,14 @@ +#ifndef _SPARC64_SCRATCHPAD_H +#define _SPARC64_SCRATCHPAD_H + +/* Sun4v scratchpad registers, accessed via ASI_SCRATCHPAD. */ + +#define SCRATCHPAD_MMU_MISS 0x00 /* Shared with OBP - set by OBP */ +#define SCRATCHPAD_CPUID 0x08 /* Shared with OBP - set by hypervisor */ +#define SCRATCHPAD_UTSBREG1 0x10 +#define SCRATCHPAD_UTSBREG2 0x18 + /* 0x20 and 0x28, hypervisor only... */ +#define SCRATCHPAD_UNUSED1 0x30 +#define SCRATCHPAD_UNUSED2 0x38 /* Reserved for OBP */ + +#endif /* !(_SPARC64_SCRATCHPAD_H) */ -- cgit v1.2.2 From e1c21c4f476f2270c98aad1fe55e5f33e25f77f5 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sat, 4 Feb 2006 03:12:14 -0800 Subject: [SPARC64]: Sun4v interrupt queue register definitions. Signed-off-by: David S. Miller --- include/asm-sparc64/intr_queue.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 include/asm-sparc64/intr_queue.h (limited to 'include') diff --git a/include/asm-sparc64/intr_queue.h b/include/asm-sparc64/intr_queue.h new file mode 100644 index 0000000000..206077dedc --- /dev/null +++ b/include/asm-sparc64/intr_queue.h @@ -0,0 +1,15 @@ +#ifndef _SPARC64_INTR_QUEUE_H +#define _SPARC64_INTR_QUEUE_H + +/* Sun4v interrupt queue registers, accessed via ASI_QUEUE. */ + +#define INTRQ_CPU_MONDO_HEAD 0x3c0 /* CPU mondo head */ +#define INTRQ_CPU_MONDO_TAIL 0x3c8 /* CPU mondo tail */ +#define INTRQ_DEVICE_MONDO_HEAD 0x3d0 /* Device mondo head */ +#define INTRQ_DEVICE_MONDO_TAIL 0x3d8 /* Device mondo tail */ +#define INTRQ_RESUM_MONDO_HEAD 0x3e0 /* Resumable error mondo head */ +#define INTRQ_RESUM_MONDO_TAIL 0x3e8 /* Resumable error mondo tail */ +#define INTRQ_NONRESUM_MONDO_HEAD 0x3f0 /* Non-resumable error mondo head */ +#define INTRQ_NONRESUM_MONDO_TAIL 0x3f8 /* Non-resumable error mondo head */ + +#endif /* !(_SPARC64_INTR_QUEUE_H) */ -- cgit v1.2.2 From d96b81533ba3d5775e45aee6986b2aa33c10801c Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sat, 4 Feb 2006 15:40:53 -0800 Subject: [SPARC64]: Add sun4v case to __GET_CPUID() patch tables. Signed-off-by: David S. Miller --- include/asm-sparc64/cpudata.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'include') diff --git a/include/asm-sparc64/cpudata.h b/include/asm-sparc64/cpudata.h index c15514f82c..4f28a85c10 100644 --- a/include/asm-sparc64/cpudata.h +++ b/include/asm-sparc64/cpudata.h @@ -68,6 +68,7 @@ struct cpuid_patch_entry { unsigned int cheetah_safari[4]; unsigned int cheetah_jbus[4]; unsigned int starfire[4]; + unsigned int sun4v[4]; }; extern struct cpuid_patch_entry __cpuid_patch, __cpuid_patch_end; #endif @@ -79,6 +80,8 @@ extern struct cpuid_patch_entry __cpuid_patch, __cpuid_patch_end; #define TRAP_BLOCK_SZ_SHIFT 6 +#include + #ifdef CONFIG_SMP #define __GET_CPUID(REG) \ @@ -105,6 +108,11 @@ extern struct cpuid_patch_entry __cpuid_patch, __cpuid_patch_end; sllx REG, 9, REG; \ or REG, 0xd0, REG; \ lduwa [REG] ASI_PHYS_BYPASS_EC_E, REG;\ + /* sun4v implementation. */ \ + mov SCRATCHPAD_CPUID, REG; \ + nop; \ + ldxa [REG] ASI_SCRATCHPAD, REG; \ + nop; \ .previous; /* Clobbers TMP, current address space PGD phys address into DEST. */ -- cgit v1.2.2 From d619d7f11670f5b1cfca30e6645e44c8a6014820 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sat, 4 Feb 2006 23:59:38 -0800 Subject: [SPARC64]: Add define for "GL" field of sun4v %tstate register. Signed-off-by: David S. Miller --- include/asm-sparc64/pstate.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/asm-sparc64/pstate.h b/include/asm-sparc64/pstate.h index 29fb74aa80..1181d73315 100644 --- a/include/asm-sparc64/pstate.h +++ b/include/asm-sparc64/pstate.h @@ -29,10 +29,11 @@ /* The V9 TSTATE Register (with SpitFire and Linux extensions). * * --------------------------------------------------------------- - * | Resv | CCR | ASI | %pil | PSTATE | Resv | CWP | + * | Resv | GL | CCR | ASI | %pil | PSTATE | Resv | CWP | * --------------------------------------------------------------- - * 63 40 39 32 31 24 23 20 19 8 7 5 4 0 + * 63 43 42 40 39 32 31 24 23 20 19 8 7 5 4 0 */ +#define TSTATE_GL _AC(0x0000070000000000,UL) /* Global reg level */ #define TSTATE_CCR _AC(0x000000ff00000000,UL) /* Condition Codes. */ #define TSTATE_XCC _AC(0x000000f000000000,UL) /* Condition Codes. */ #define TSTATE_XNEG _AC(0x0000008000000000,UL) /* %xcc Negative. */ -- cgit v1.2.2 From 936f482af1743141d637483ec10eb881537c26dc Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 5 Feb 2006 21:29:28 -0800 Subject: [SPARC64]: Add initial code to twiddle %gl on trap entry/exit. Instead of setting/clearing PSTATE_AG we have to change the %gl register value on sun4v. Signed-off-by: David S. Miller --- include/asm-sparc64/cpudata.h | 5 +++++ include/asm-sparc64/head.h | 4 ++++ 2 files changed, 9 insertions(+) (limited to 'include') diff --git a/include/asm-sparc64/cpudata.h b/include/asm-sparc64/cpudata.h index 4f28a85c10..8666440c89 100644 --- a/include/asm-sparc64/cpudata.h +++ b/include/asm-sparc64/cpudata.h @@ -73,6 +73,11 @@ struct cpuid_patch_entry { extern struct cpuid_patch_entry __cpuid_patch, __cpuid_patch_end; #endif +struct gl_1insn_patch_entry { + unsigned int addr; + unsigned int insn; +}; +extern struct gl_1insn_patch_entry __gl_1insn_patch, __gl_1insn_patch_end; #endif /* !(__ASSEMBLY__) */ #define TRAP_PER_CPU_THREAD 0x00 diff --git a/include/asm-sparc64/head.h b/include/asm-sparc64/head.h index 731c842f3d..ff76c0981b 100644 --- a/include/asm-sparc64/head.h +++ b/include/asm-sparc64/head.h @@ -4,6 +4,10 @@ #include + /* wrpr %g0, val, %gl */ +#define SET_GL(val) \ + .word 0xa1902000 | val + #define KERNBASE 0x400000 #define PTREGS_OFF (STACK_BIAS + STACKFRAME_SZ) -- cgit v1.2.2 From 314981ac7177a933319e3c071a5cf0a579205e6e Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 5 Feb 2006 21:59:03 -0800 Subject: [SPARC64]: Kill all %pstate changes in context switch code. They are totally unnecessary because: 1) Interrupts are already disabled when switch_to() runs. 2) We don't use hard-coded alternate globals any longer. This found a case in rtrap, which still assumed alternate global %g6 was current_thread_info(), and that is fixed by this changeset as well. Signed-off-by: David S. Miller --- include/asm-sparc64/system.h | 5 ----- 1 file changed, 5 deletions(-) (limited to 'include') diff --git a/include/asm-sparc64/system.h b/include/asm-sparc64/system.h index 26c0807af3..a18ec87a52 100644 --- a/include/asm-sparc64/system.h +++ b/include/asm-sparc64/system.h @@ -213,7 +213,6 @@ do { if (test_thread_flag(TIF_PERFCTR)) { \ task_thread_info(next); \ __asm__ __volatile__( \ "mov %%g4, %%g7\n\t" \ - "wrpr %%g0, 0x95, %%pstate\n\t" \ "stx %%i6, [%%sp + 2047 + 0x70]\n\t" \ "stx %%i7, [%%sp + 2047 + 0x78]\n\t" \ "rdpr %%wstate, %%o5\n\t" \ @@ -227,14 +226,10 @@ do { if (test_thread_flag(TIF_PERFCTR)) { \ "ldx [%%g6 + %3], %%o6\n\t" \ "ldub [%%g6 + %2], %%o5\n\t" \ "ldub [%%g6 + %4], %%o7\n\t" \ - "mov %%g6, %%l2\n\t" \ "wrpr %%o5, 0x0, %%wstate\n\t" \ "ldx [%%sp + 2047 + 0x70], %%i6\n\t" \ "ldx [%%sp + 2047 + 0x78], %%i7\n\t" \ - "wrpr %%g0, 0x94, %%pstate\n\t" \ - "mov %%l2, %%g6\n\t" \ "ldx [%%g6 + %6], %%g4\n\t" \ - "wrpr %%g0, 0x96, %%pstate\n\t" \ "brz,pt %%o7, 1f\n\t" \ " mov %%g7, %0\n\t" \ "b,a ret_from_syscall\n\t" \ -- cgit v1.2.2 From 45fec05f805a113372c9a7ff4c653ac749f6921c Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 5 Feb 2006 22:27:28 -0800 Subject: [SPARC64]: Sanitize %pstate writes for sun4v. If we're just switching between different alternate global sets, nop it out on sun4v. Also, get rid of all of the alternate global save/restore in the OBP CIF trampoline code. Signed-off-by: David S. Miller --- include/asm-sparc64/cpudata.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'include') diff --git a/include/asm-sparc64/cpudata.h b/include/asm-sparc64/cpudata.h index 8666440c89..998145b926 100644 --- a/include/asm-sparc64/cpudata.h +++ b/include/asm-sparc64/cpudata.h @@ -78,6 +78,12 @@ struct gl_1insn_patch_entry { unsigned int insn; }; extern struct gl_1insn_patch_entry __gl_1insn_patch, __gl_1insn_patch_end; + +struct gl_2insn_patch_entry { + unsigned int addr; + unsigned int insns[2]; +}; +extern struct gl_2insn_patch_entry __gl_2insn_patch, __gl_2insn_patch_end; #endif /* !(__ASSEMBLY__) */ #define TRAP_PER_CPU_THREAD 0x00 -- cgit v1.2.2 From d257d5da39a78b32721ca84b2ba7f461f2f7ed7f Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 6 Feb 2006 23:44:37 -0800 Subject: [SPARC64]: Initial sun4v TLB miss handling infrastructure. Things are a little tricky because, unlike sun4u, we have to: 1) do a hypervisor trap to do the TLB load. 2) do the TSB lookup calculations by hand Signed-off-by: David S. Miller --- include/asm-sparc64/cpudata.h | 8 +++++++- include/asm-sparc64/tsb.h | 11 ++++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/asm-sparc64/cpudata.h b/include/asm-sparc64/cpudata.h index 998145b926..a3dc4afc4b 100644 --- a/include/asm-sparc64/cpudata.h +++ b/include/asm-sparc64/cpudata.h @@ -6,6 +6,8 @@ #ifndef _SPARC64_CPUDATA_H #define _SPARC64_CPUDATA_H +#include + #ifndef __ASSEMBLY__ #include @@ -57,6 +59,9 @@ struct trap_per_cpu { /* D-cache line 2 */ unsigned long __pad2[4]; + +/* Dcache lines 3 and 4 */ + struct hv_fault_status fault_info; } __attribute__((aligned(64))); extern struct trap_per_cpu trap_block[NR_CPUS]; extern void init_cur_cpu_trap(void); @@ -88,8 +93,9 @@ extern struct gl_2insn_patch_entry __gl_2insn_patch, __gl_2insn_patch_end; #define TRAP_PER_CPU_THREAD 0x00 #define TRAP_PER_CPU_PGD_PADDR 0x08 +#define TRAP_PER_CPU_FAULT_INFO 0x20 -#define TRAP_BLOCK_SZ_SHIFT 6 +#define TRAP_BLOCK_SZ_SHIFT 7 #include diff --git a/include/asm-sparc64/tsb.h b/include/asm-sparc64/tsb.h index 44709cde56..7f3abc32c4 100644 --- a/include/asm-sparc64/tsb.h +++ b/include/asm-sparc64/tsb.h @@ -53,6 +53,14 @@ * kernel image, so we don't play these games for swapper_tsb access. */ #ifndef __ASSEMBLY__ +struct tsb_ldquad_phys_patch_entry { + unsigned int addr; + unsigned int sun4u_insn; + unsigned int sun4v_insn; +}; +extern struct tsb_ldquad_phys_patch_entry __tsb_ldquad_phys_patch, + __tsb_ldquad_phys_patch_end; + struct tsb_phys_patch_entry { unsigned int addr; unsigned int insn; @@ -61,9 +69,10 @@ extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end; #endif #define TSB_LOAD_QUAD(TSB, REG) \ 661: ldda [TSB] ASI_NUCLEUS_QUAD_LDD, REG; \ - .section .tsb_phys_patch, "ax"; \ + .section .tsb_ldquad_phys_patch, "ax"; \ .word 661b; \ ldda [TSB] ASI_QUAD_LDD_PHYS, REG; \ + ldda [TSB] ASI_QUAD_LDD_PHYS_4V, REG; \ .previous #define TSB_LOAD_TAG_HIGH(TSB, REG) \ -- cgit v1.2.2 From df7d6aec96ab98cb182dd5138a85bdc363a9bf0d Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 7 Feb 2006 00:00:16 -0800 Subject: [SPARC64]: Rename gl_{1,2}insn_patch --> sun4v_{1,2}insn_patch Signed-off-by: David S. Miller --- include/asm-sparc64/cpudata.h | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/asm-sparc64/cpudata.h b/include/asm-sparc64/cpudata.h index a3dc4afc4b..26b1dc9afb 100644 --- a/include/asm-sparc64/cpudata.h +++ b/include/asm-sparc64/cpudata.h @@ -78,17 +78,20 @@ struct cpuid_patch_entry { extern struct cpuid_patch_entry __cpuid_patch, __cpuid_patch_end; #endif -struct gl_1insn_patch_entry { +struct sun4v_1insn_patch_entry { unsigned int addr; unsigned int insn; }; -extern struct gl_1insn_patch_entry __gl_1insn_patch, __gl_1insn_patch_end; +extern struct sun4v_1insn_patch_entry __sun4v_1insn_patch, + __sun4v_1insn_patch_end; -struct gl_2insn_patch_entry { +struct sun4v_2insn_patch_entry { unsigned int addr; unsigned int insns[2]; }; -extern struct gl_2insn_patch_entry __gl_2insn_patch, __gl_2insn_patch_end; +extern struct sun4v_2insn_patch_entry __sun4v_2insn_patch, + __sun4v_2insn_patch_end; + #endif /* !(__ASSEMBLY__) */ #define TRAP_PER_CPU_THREAD 0x00 -- cgit v1.2.2 From 89a5264f065672a882f555228000614a6b2182b7 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 7 Feb 2006 21:15:41 -0800 Subject: [SPARC64]: asm/cpudata.h needs asm/asi.h For the expansion of __GET_CPUID() on SMP. Signed-off-by: David S. Miller --- include/asm-sparc64/cpudata.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/asm-sparc64/cpudata.h b/include/asm-sparc64/cpudata.h index 26b1dc9afb..8a171ad772 100644 --- a/include/asm-sparc64/cpudata.h +++ b/include/asm-sparc64/cpudata.h @@ -7,6 +7,7 @@ #define _SPARC64_CPUDATA_H #include +#include #ifndef __ASSEMBLY__ @@ -130,9 +131,9 @@ extern struct sun4v_2insn_patch_entry __sun4v_2insn_patch, lduwa [REG] ASI_PHYS_BYPASS_EC_E, REG;\ /* sun4v implementation. */ \ mov SCRATCHPAD_CPUID, REG; \ - nop; \ ldxa [REG] ASI_SCRATCHPAD, REG; \ nop; \ + nop; \ .previous; /* Clobbers TMP, current address space PGD phys address into DEST. */ -- cgit v1.2.2 From 481295f982b21b1dbe71cbf41d3a93028fee30d1 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 7 Feb 2006 21:51:08 -0800 Subject: [SPARC64]: Register per-cpu fault status area with sun4v hypervisor. Signed-off-by: David S. Miller --- include/asm-sparc64/pgtable.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/asm-sparc64/pgtable.h b/include/asm-sparc64/pgtable.h index 2b2ecd6104..c42c06a37d 100644 --- a/include/asm-sparc64/pgtable.h +++ b/include/asm-sparc64/pgtable.h @@ -437,6 +437,7 @@ extern unsigned long get_fb_unmapped_area(struct file *filp, unsigned long, #define HAVE_ARCH_FB_UNMAPPED_AREA extern void pgtable_cache_init(void); +extern void sun4v_register_fault_status(void); #endif /* !(__ASSEMBLY__) */ -- cgit v1.2.2 From 8b11bd12aff76e02cdc2cbc9e439bba88d281223 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 7 Feb 2006 22:13:05 -0800 Subject: [SPARC64]: Patch up mmu context register writes for sun4v. sun4v uses ASI_MMU instead of ASI_DMMU Signed-off-by: David S. Miller --- include/asm-sparc64/mmu_context.h | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'include') diff --git a/include/asm-sparc64/mmu_context.h b/include/asm-sparc64/mmu_context.h index 1d23267882..2760353591 100644 --- a/include/asm-sparc64/mmu_context.h +++ b/include/asm-sparc64/mmu_context.h @@ -41,11 +41,16 @@ extern void smp_tsb_sync(struct mm_struct *mm); /* Set MMU context in the actual hardware. */ #define load_secondary_context(__mm) \ - __asm__ __volatile__("stxa %0, [%1] %2\n\t" \ - "flush %%g6" \ - : /* No outputs */ \ - : "r" (CTX_HWBITS((__mm)->context)), \ - "r" (SECONDARY_CONTEXT), "i" (ASI_DMMU)) + __asm__ __volatile__( \ + "\n661: stxa %0, [%1] %2\n" \ + " .section .sun4v_1insn_patch, \"ax\"\n" \ + " .word 661b\n" \ + " stxa %0, [%1] %3\n" \ + " .previous\n" \ + " flush %%g6\n" \ + : /* No outputs */ \ + : "r" (CTX_HWBITS((__mm)->context)), \ + "r" (SECONDARY_CONTEXT), "i" (ASI_DMMU), "i" (ASI_MMU)) extern void __flush_tlb_mm(unsigned long, unsigned long); -- cgit v1.2.2 From 3bfd6f3e77f58479ec53aa91d0b078abbb4c0868 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 7 Feb 2006 22:49:38 -0800 Subject: [SPARC64]: Fix some comment typos in asm/hypervisor.h Signed-off-by: David S. Miller --- include/asm-sparc64/hypervisor.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/asm-sparc64/hypervisor.h b/include/asm-sparc64/hypervisor.h index 9c8e453abe..b4e0d52acd 100644 --- a/include/asm-sparc64/hypervisor.h +++ b/include/asm-sparc64/hypervisor.h @@ -272,17 +272,19 @@ * EBADALIGN Base real address is not correctly aligned * for size. * - * Configure the given queue to be placed at the givem base real + * Configure the given queue to be placed at the given base real * address, with the given number of entries. The number of entries * must be a power of 2. The base real address must be aligned * exactly to match the queue size. Each queue entry is 64 bytes * long, so for example a 32 entry queue must be aligned on a 2048 * byte real address boundary. * - * The specified queue is unconfigured is number of entries is given as zero. + * The specified queue is unconfigured if the number of entries is given + * as zero. * * For the current version of this API service, the argument queue is defined * as follows: + * * queue description * ----- ------------------------- * 0x3c cpu mondo queue -- cgit v1.2.2 From 7202c55c5c57d2ad4611a751544c9368d7fba93a Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 7 Feb 2006 22:53:56 -0800 Subject: [SPARC64]: Add sun4v mondo queue bases to struct trap_per_cpu. Also, correct TRAP_PER_CPU_FAULT_INFO define, it should be 0x40 not 0x20. Signed-off-by: David S. Miller --- include/asm-sparc64/cpudata.h | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) (limited to 'include') diff --git a/include/asm-sparc64/cpudata.h b/include/asm-sparc64/cpudata.h index 8a171ad772..492314b534 100644 --- a/include/asm-sparc64/cpudata.h +++ b/include/asm-sparc64/cpudata.h @@ -53,15 +53,18 @@ DECLARE_PER_CPU(cpuinfo_sparc, __cpu_data); */ struct thread_info; struct trap_per_cpu { -/* D-cache line 1 */ +/* D-cache line 1: Basic thread information */ struct thread_info *thread; unsigned long pgd_paddr; unsigned long __pad1[2]; -/* D-cache line 2 */ - unsigned long __pad2[4]; +/* D-cache line 2: Sun4V Mondo Queue pointers */ + unsigned long cpu_mondo_pa; + unsigned long dev_mondo_pa; + unsigned long resum_mondo_pa; + unsigned long nonresum_mondo_pa; -/* Dcache lines 3 and 4 */ +/* Dcache lines 3 and 4: Hypervisor Fault Status */ struct hv_fault_status fault_info; } __attribute__((aligned(64))); extern struct trap_per_cpu trap_block[NR_CPUS]; @@ -95,11 +98,15 @@ extern struct sun4v_2insn_patch_entry __sun4v_2insn_patch, #endif /* !(__ASSEMBLY__) */ -#define TRAP_PER_CPU_THREAD 0x00 -#define TRAP_PER_CPU_PGD_PADDR 0x08 -#define TRAP_PER_CPU_FAULT_INFO 0x20 +#define TRAP_PER_CPU_THREAD 0x00 +#define TRAP_PER_CPU_PGD_PADDR 0x08 +#define TRAP_PER_CPU_CPU_MONDO_PA 0x20 +#define TRAP_PER_CPU_DEV_MONDO_PA 0x28 +#define TRAP_PER_CPU_RESUM_MONDO_PA 0x30 +#define TRAP_PER_CPU_NONRESUM_MONDO_PA 0x38 +#define TRAP_PER_CPU_FAULT_INFO 0x40 -#define TRAP_BLOCK_SZ_SHIFT 7 +#define TRAP_BLOCK_SZ_SHIFT 7 #include -- cgit v1.2.2 From 5b0c0572fcd6204675c5f7ddfa572b5017f817dd Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 8 Feb 2006 02:53:50 -0800 Subject: [SPARC64]: Sun4v interrupt handling. Sun4v has 4 interrupt queues: cpu, device, resumable errors, and non-resumable errors. A set of head/tail offset pointers help maintain a work queue in physical memory. The entries are 64-bytes in size. Each queue is allocated then registered with the hypervisor as we bring cpus up. The two error queues each get a kernel side buffer that we use to quickly empty the main interrupt queue before we call up to C code to log the event and possibly take evasive action. Signed-off-by: David S. Miller --- include/asm-sparc64/cpudata.h | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) (limited to 'include') diff --git a/include/asm-sparc64/cpudata.h b/include/asm-sparc64/cpudata.h index 492314b534..7f0a74ec47 100644 --- a/include/asm-sparc64/cpudata.h +++ b/include/asm-sparc64/cpudata.h @@ -53,16 +53,17 @@ DECLARE_PER_CPU(cpuinfo_sparc, __cpu_data); */ struct thread_info; struct trap_per_cpu { -/* D-cache line 1: Basic thread information */ +/* D-cache line 1: Basic thread information, cpu and device mondo queues */ struct thread_info *thread; unsigned long pgd_paddr; - unsigned long __pad1[2]; - -/* D-cache line 2: Sun4V Mondo Queue pointers */ unsigned long cpu_mondo_pa; unsigned long dev_mondo_pa; + +/* D-cache line 2: Error Mondo Queue and kernel buffer pointers */ unsigned long resum_mondo_pa; + unsigned long resum_kernel_buf_pa; unsigned long nonresum_mondo_pa; + unsigned long nonresum_kernel_buf_pa; /* Dcache lines 3 and 4: Hypervisor Fault Status */ struct hv_fault_status fault_info; @@ -100,10 +101,12 @@ extern struct sun4v_2insn_patch_entry __sun4v_2insn_patch, #define TRAP_PER_CPU_THREAD 0x00 #define TRAP_PER_CPU_PGD_PADDR 0x08 -#define TRAP_PER_CPU_CPU_MONDO_PA 0x20 -#define TRAP_PER_CPU_DEV_MONDO_PA 0x28 -#define TRAP_PER_CPU_RESUM_MONDO_PA 0x30 -#define TRAP_PER_CPU_NONRESUM_MONDO_PA 0x38 +#define TRAP_PER_CPU_CPU_MONDO_PA 0x10 +#define TRAP_PER_CPU_DEV_MONDO_PA 0x18 +#define TRAP_PER_CPU_RESUM_MONDO_PA 0x20 +#define TRAP_PER_CPU_RESUM_KBUF_PA 0x28 +#define TRAP_PER_CPU_NONRESUM_MONDO_PA 0x30 +#define TRAP_PER_CPU_NONRESUM_KBUF_PA 0x38 #define TRAP_PER_CPU_FAULT_INFO 0x40 #define TRAP_BLOCK_SZ_SHIFT 7 @@ -188,6 +191,9 @@ extern struct sun4v_2insn_patch_entry __sun4v_2insn_patch, #else +#define __GET_CPUID(REG) \ + mov 0, REG; + /* Uniprocessor versions, we know the cpuid is zero. */ #define TRAP_LOAD_PGD_PHYS(DEST, TMP) \ sethi %hi(trap_block), DEST; \ -- cgit v1.2.2 From 1d2f1f90a1e004b0c1b8a73ed4394a93f09104b3 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 8 Feb 2006 16:41:20 -0800 Subject: [SPARC64]: Sun4v cross-call sending support. Technically the hypervisor call supports sending in a list of all cpus to get the cross-call, but I only pass in one cpu at a time for now. The multi-cpu support is there, just ifdef'd out so it's easy to enable or delete it later. Signed-off-by: David S. Miller --- include/asm-sparc64/cpudata.h | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/asm-sparc64/cpudata.h b/include/asm-sparc64/cpudata.h index 7f0a74ec47..338b0ca5b5 100644 --- a/include/asm-sparc64/cpudata.h +++ b/include/asm-sparc64/cpudata.h @@ -65,8 +65,16 @@ struct trap_per_cpu { unsigned long nonresum_mondo_pa; unsigned long nonresum_kernel_buf_pa; -/* Dcache lines 3 and 4: Hypervisor Fault Status */ +/* Dcache lines 3, 4, 5, and 6: Hypervisor Fault Status */ struct hv_fault_status fault_info; + +/* Dcache line 7: Physical addresses of CPU send mondo block and CPU list. */ + unsigned long cpu_mondo_block_pa; + unsigned long cpu_list_pa; + unsigned long __pad1[2]; + +/* Dcache line 8: Unused, needed to keep trap_block a power-of-2 in size. */ + unsigned long __pad2[4]; } __attribute__((aligned(64))); extern struct trap_per_cpu trap_block[NR_CPUS]; extern void init_cur_cpu_trap(void); @@ -108,8 +116,10 @@ extern struct sun4v_2insn_patch_entry __sun4v_2insn_patch, #define TRAP_PER_CPU_NONRESUM_MONDO_PA 0x30 #define TRAP_PER_CPU_NONRESUM_KBUF_PA 0x38 #define TRAP_PER_CPU_FAULT_INFO 0x40 +#define TRAP_PER_CPU_CPU_MONDO_BLOCK_PA 0xc0 +#define TRAP_PER_CPU_CPU_LIST_PA 0xc8 -#define TRAP_BLOCK_SZ_SHIFT 7 +#define TRAP_BLOCK_SZ_SHIFT 8 #include -- cgit v1.2.2 From d82ace7dc4073b090a55b9740700e32b9a9ae302 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 9 Feb 2006 02:52:44 -0800 Subject: [SPARC64]: Detect sun4v early in boot process. We look for "SUNW,sun4v" in the 'compatible' property of the root OBP device tree node. Protect every %ver register access, to make sure it is not touched on sun4v, as %ver is hyperprivileged there. Lock kernel TLB entries using hypervisor calls instead of calls into OBP. Signed-off-by: David S. Miller --- include/asm-sparc64/head.h | 6 ++++++ include/asm-sparc64/oplib.h | 3 +++ 2 files changed, 9 insertions(+) (limited to 'include') diff --git a/include/asm-sparc64/head.h b/include/asm-sparc64/head.h index ff76c0981b..c4ac3e87aa 100644 --- a/include/asm-sparc64/head.h +++ b/include/asm-sparc64/head.h @@ -24,6 +24,12 @@ #define PANTHER_IMPL 0x0019 /* Ultra-IV+ */ #define SERRANO_IMPL 0x0022 /* Ultra-IIIi+ */ +#define BRANCH_IF_SUN4V(tmp1,label) \ + sethi %hi(is_sun4v), %tmp1; \ + lduw [%tmp1 + %lo(is_sun4v)], %tmp1; \ + brnz,pn %tmp1, label; \ + nop + #define BRANCH_IF_CHEETAH_BASE(tmp1,tmp2,label) \ rdpr %ver, %tmp1; \ sethi %hi(__CHEETAH_ID), %tmp2; \ diff --git a/include/asm-sparc64/oplib.h b/include/asm-sparc64/oplib.h index 3c59b2693f..2ea545b931 100644 --- a/include/asm-sparc64/oplib.h +++ b/include/asm-sparc64/oplib.h @@ -39,6 +39,9 @@ extern int prom_stdin, prom_stdout; extern int prom_chosen_node; /* Helper values and strings in arch/sparc64/kernel/head.S */ +extern const char prom_peer_name[]; +extern const char prom_compatible_name[]; +extern const char prom_root_compatible[]; extern const char prom_finddev_name[]; extern const char prom_chosen_path[]; extern const char prom_getprop_name[]; -- cgit v1.2.2 From aa9143b9719c07fb6f1f6207790c9c5086ae07e7 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 9 Feb 2006 16:12:22 -0800 Subject: [SPARC64]: Implement sun4v TSB miss handlers. When we register a TSB with the hypervisor, so that it or hardware can handle TLB misses and do the TSB walk for us, the hypervisor traps down to these trap when it incurs a TSB miss. Processing is simple, we load the missing virtual address and context, and do a full page table walk. Signed-off-by: David S. Miller --- include/asm-sparc64/ttable.h | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'include') diff --git a/include/asm-sparc64/ttable.h b/include/asm-sparc64/ttable.h index f912f52c0c..972f913709 100644 --- a/include/asm-sparc64/ttable.h +++ b/include/asm-sparc64/ttable.h @@ -180,6 +180,26 @@ #define KPROBES_TRAP(lvl) TRAP_ARG(bad_trap, lvl) #endif +#define SUN4V_ITSB_MISS \ + mov SCRATCHPAD_CPUID, %g1; \ + ldxa [%g1] ASI_SCRATCHPAD, %g2; \ + ldxa [%g1 + %g1] ASI_SCRATCHPAD, %g1;\ + sethi %hi(trap_block), %g5; \ + sllx %g2, TRAP_BLOCK_SZ_SHIFT, %g2; \ + or %g5, %lo(trap_block), %g5; \ + ba,pt %xcc, sun4v_itsb_miss; \ + add %g5, %g2, %g5; + +#define SUN4V_DTSB_MISS \ + mov SCRATCHPAD_CPUID, %g1; \ + ldxa [%g1] ASI_SCRATCHPAD, %g2; \ + ldxa [%g1 + %g1] ASI_SCRATCHPAD, %g1;\ + sethi %hi(trap_block), %g5; \ + sllx %g2, TRAP_BLOCK_SZ_SHIFT, %g2; \ + or %g5, %lo(trap_block), %g5; \ + ba,pt %xcc, sun4v_dtsb_miss; \ + add %g5, %g2, %g5; + /* Before touching these macros, you owe it to yourself to go and * see how arch/sparc64/kernel/winfixup.S works... -DaveM * -- cgit v1.2.2 From 618e9ed98aed924a1fc664eb6522db4a5e927043 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 9 Feb 2006 17:21:53 -0800 Subject: [SPARC64]: Hypervisor TSB context switching. Signed-off-by: David S. Miller --- include/asm-sparc64/mmu.h | 16 +++++++++------- include/asm-sparc64/mmu_context.h | 10 +++++++--- 2 files changed, 16 insertions(+), 10 deletions(-) (limited to 'include') diff --git a/include/asm-sparc64/mmu.h b/include/asm-sparc64/mmu.h index 55e622711b..473d990848 100644 --- a/include/asm-sparc64/mmu.h +++ b/include/asm-sparc64/mmu.h @@ -4,6 +4,7 @@ #include #include #include +#include /* * For the 8k pagesize kernel, use only 10 hw context bits to optimize some @@ -101,13 +102,14 @@ extern void __tsb_insert(unsigned long ent, unsigned long tag, unsigned long pte extern void tsb_flush(unsigned long ent, unsigned long tag); typedef struct { - unsigned long sparc64_ctx_val; - struct tsb *tsb; - unsigned long tsb_rss_limit; - unsigned long tsb_nentries; - unsigned long tsb_reg_val; - unsigned long tsb_map_vaddr; - unsigned long tsb_map_pte; + unsigned long sparc64_ctx_val; + struct tsb *tsb; + unsigned long tsb_rss_limit; + unsigned long tsb_nentries; + unsigned long tsb_reg_val; + unsigned long tsb_map_vaddr; + unsigned long tsb_map_pte; + struct hv_tsb_descr tsb_descr; } mm_context_t; #endif /* !__ASSEMBLY__ */ diff --git a/include/asm-sparc64/mmu_context.h b/include/asm-sparc64/mmu_context.h index 2760353591..eb660b1609 100644 --- a/include/asm-sparc64/mmu_context.h +++ b/include/asm-sparc64/mmu_context.h @@ -22,14 +22,18 @@ extern void get_new_mmu_context(struct mm_struct *mm); extern int init_new_context(struct task_struct *tsk, struct mm_struct *mm); extern void destroy_context(struct mm_struct *mm); -extern void __tsb_context_switch(unsigned long pgd_pa, unsigned long tsb_reg, - unsigned long tsb_vaddr, unsigned long tsb_pte); +extern void __tsb_context_switch(unsigned long pgd_pa, + unsigned long tsb_reg, + unsigned long tsb_vaddr, + unsigned long tsb_pte, + unsigned long tsb_descr_pa); static inline void tsb_context_switch(struct mm_struct *mm) { __tsb_context_switch(__pa(mm->pgd), mm->context.tsb_reg_val, mm->context.tsb_map_vaddr, - mm->context.tsb_map_pte); + mm->context.tsb_map_pte, + __pa(&mm->context.tsb_descr)); } extern void tsb_grow(struct mm_struct *mm, unsigned long mm_rss, gfp_t gfp_flags); -- cgit v1.2.2 From 5fe91cf6254c8f23d90efb5fc11fff57dd5ab8dd Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 9 Feb 2006 20:45:26 -0800 Subject: [SPARC]: Clean up idprom header files. Delete unused macros, and use fixed sized types in sparc32 header. Signed-off-by: David S. Miller --- include/asm-sparc/idprom.h | 26 +++++++++----------------- include/asm-sparc64/idprom.h | 12 +----------- 2 files changed, 10 insertions(+), 28 deletions(-) (limited to 'include') diff --git a/include/asm-sparc/idprom.h b/include/asm-sparc/idprom.h index d856e640ac..59083ed852 100644 --- a/include/asm-sparc/idprom.h +++ b/include/asm-sparc/idprom.h @@ -7,27 +7,19 @@ #ifndef _SPARC_IDPROM_H #define _SPARC_IDPROM_H -/* Offset into the EEPROM where the id PROM is located on the 4c */ -#define IDPROM_OFFSET 0x7d8 +#include -/* On sun4m; physical. */ -/* MicroSPARC(-II) does not decode 31rd bit, but it works. */ -#define IDPROM_OFFSET_M 0xfd8 - -struct idprom -{ - unsigned char id_format; /* Format identifier (always 0x01) */ - unsigned char id_machtype; /* Machine type */ - unsigned char id_ethaddr[6]; /* Hardware ethernet address */ - long id_date; /* Date of manufacture */ - unsigned int id_sernum:24; /* Unique serial number */ - unsigned char id_cksum; /* Checksum - xor of the data bytes */ - unsigned char reserved[16]; +struct idprom { + u8 id_format; /* Format identifier (always 0x01) */ + u8 id_machtype; /* Machine type */ + u8 id_ethaddr[6]; /* Hardware ethernet address */ + s32 id_date; /* Date of manufacture */ + u32 id_sernum:24; /* Unique serial number */ + u8 id_cksum; /* Checksum - xor of the data bytes */ + u8 reserved[16]; }; extern struct idprom *idprom; extern void idprom_init(void); -#define IDPROM_SIZE (sizeof(struct idprom)) - #endif /* !(_SPARC_IDPROM_H) */ diff --git a/include/asm-sparc64/idprom.h b/include/asm-sparc64/idprom.h index 701483c546..77fbf98738 100644 --- a/include/asm-sparc64/idprom.h +++ b/include/asm-sparc64/idprom.h @@ -9,15 +9,7 @@ #include -/* Offset into the EEPROM where the id PROM is located on the 4c */ -#define IDPROM_OFFSET 0x7d8 - -/* On sun4m; physical. */ -/* MicroSPARC(-II) does not decode 31rd bit, but it works. */ -#define IDPROM_OFFSET_M 0xfd8 - -struct idprom -{ +struct idprom { u8 id_format; /* Format identifier (always 0x01) */ u8 id_machtype; /* Machine type */ u8 id_ethaddr[6]; /* Hardware ethernet address */ @@ -30,6 +22,4 @@ struct idprom extern struct idprom *idprom; extern void idprom_init(void); -#define IDPROM_SIZE (sizeof(struct idprom)) - #endif /* !(_SPARC_IDPROM_H) */ -- cgit v1.2.2 From 8f6a93a196ba6c569c3e8daa6e81cca7e3ba81b1 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 9 Feb 2006 21:32:07 -0800 Subject: [SPARC64]: Beginnings of SUN4V PCI controller support. Abstract out IOMMU operations so that we can have a different set of calls on sun4v, which needs to do things through hypervisor calls. Signed-off-by: David S. Miller --- include/asm-sparc64/pci.h | 56 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 45 insertions(+), 11 deletions(-) (limited to 'include') diff --git a/include/asm-sparc64/pci.h b/include/asm-sparc64/pci.h index 89bd71b1c0..7c5a589ea4 100644 --- a/include/asm-sparc64/pci.h +++ b/include/asm-sparc64/pci.h @@ -41,10 +41,26 @@ static inline void pcibios_penalize_isa_irq(int irq, int active) struct pci_dev; +struct pci_iommu_ops { + void *(*alloc_consistent)(struct pci_dev *, size_t, dma_addr_t *); + void (*free_consistent)(struct pci_dev *, size_t, void *, dma_addr_t); + dma_addr_t (*map_single)(struct pci_dev *, void *, size_t, int); + void (*unmap_single)(struct pci_dev *, dma_addr_t, size_t, int); + int (*map_sg)(struct pci_dev *, struct scatterlist *, int, int); + void (*unmap_sg)(struct pci_dev *, struct scatterlist *, int, int); + void (*dma_sync_single_for_cpu)(struct pci_dev *, dma_addr_t, size_t, int); + void (*dma_sync_sg_for_cpu)(struct pci_dev *, struct scatterlist *, int, int); +}; + +extern struct pci_iommu_ops *pci_iommu_ops; + /* Allocate and map kernel buffer using consistent mode DMA for a device. * hwdev should be valid struct pci_dev pointer for PCI devices. */ -extern void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, dma_addr_t *dma_handle); +static inline void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, dma_addr_t *dma_handle) +{ + return pci_iommu_ops->alloc_consistent(hwdev, size, dma_handle); +} /* Free and unmap a consistent DMA buffer. * cpu_addr is what was returned from pci_alloc_consistent, @@ -54,7 +70,10 @@ extern void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, dma_addr_t * References to the memory and mappings associated with cpu_addr/dma_addr * past this call are illegal. */ -extern void pci_free_consistent(struct pci_dev *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle); +static inline void pci_free_consistent(struct pci_dev *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle) +{ + return pci_iommu_ops->free_consistent(hwdev, size, vaddr, dma_handle); +} /* Map a single buffer of the indicated size for DMA in streaming mode. * The 32-bit bus address to use is returned. @@ -62,7 +81,10 @@ extern void pci_free_consistent(struct pci_dev *hwdev, size_t size, void *vaddr, * Once the device is given the dma address, the device owns this memory * until either pci_unmap_single or pci_dma_sync_single_for_cpu is performed. */ -extern dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr, size_t size, int direction); +static inline dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr, size_t size, int direction) +{ + return pci_iommu_ops->map_single(hwdev, ptr, size, direction); +} /* Unmap a single streaming mode DMA translation. The dma_addr and size * must match what was provided for in a previous pci_map_single call. All @@ -71,7 +93,10 @@ extern dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr, size_t size, * After this call, reads by the cpu to the buffer are guaranteed to see * whatever the device wrote there. */ -extern void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr, size_t size, int direction); +static inline void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr, size_t size, int direction) +{ + pci_iommu_ops->unmap_single(hwdev, dma_addr, size, direction); +} /* No highmem on sparc64, plus we have an IOMMU, so mapping pages is easy. */ #define pci_map_page(dev, page, off, size, dir) \ @@ -107,15 +132,19 @@ extern void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr, size_t * Device ownership issues as mentioned above for pci_map_single are * the same here. */ -extern int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, - int nents, int direction); +static inline int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction) +{ + return pci_iommu_ops->map_sg(hwdev, sg, nents, direction); +} /* Unmap a set of streaming mode DMA translations. * Again, cpu read rules concerning calls here are the same as for * pci_unmap_single() above. */ -extern void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg, - int nhwents, int direction); +static inline void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nhwents, int direction) +{ + pci_iommu_ops->unmap_sg(hwdev, sg, nhwents, direction); +} /* Make physical memory consistent for a single * streaming mode DMA translation after a transfer. @@ -127,8 +156,10 @@ extern void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg, * must first perform a pci_dma_sync_for_device, and then the * device again owns the buffer. */ -extern void pci_dma_sync_single_for_cpu(struct pci_dev *hwdev, dma_addr_t dma_handle, - size_t size, int direction); +static inline void pci_dma_sync_single_for_cpu(struct pci_dev *hwdev, dma_addr_t dma_handle, size_t size, int direction) +{ + pci_iommu_ops->dma_sync_single_for_cpu(hwdev, dma_handle, size, direction); +} static inline void pci_dma_sync_single_for_device(struct pci_dev *hwdev, dma_addr_t dma_handle, @@ -144,7 +175,10 @@ pci_dma_sync_single_for_device(struct pci_dev *hwdev, dma_addr_t dma_handle, * The same as pci_dma_sync_single_* but for a scatter-gather list, * same rules and usage. */ -extern void pci_dma_sync_sg_for_cpu(struct pci_dev *hwdev, struct scatterlist *sg, int nelems, int direction); +static inline void pci_dma_sync_sg_for_cpu(struct pci_dev *hwdev, struct scatterlist *sg, int nelems, int direction) +{ + pci_iommu_ops->dma_sync_sg_for_cpu(hwdev, sg, nelems, direction); +} static inline void pci_dma_sync_sg_for_device(struct pci_dev *hwdev, struct scatterlist *sg, -- cgit v1.2.2 From bade5622167181844cd4e60087971c1f949e149f Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 9 Feb 2006 22:05:54 -0800 Subject: [SPARC64]: More SUN4V PCI controller work. Add assembler file for PCI hypervisor calls. Setup basic skeleton of SUN4V PCI controller driver. Add 32-bit devhandle to PBM struct, as this is needed for hypervisor calls. Signed-off-by: David S. Miller --- include/asm-sparc64/pbm.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include') diff --git a/include/asm-sparc64/pbm.h b/include/asm-sparc64/pbm.h index dd35a2c779..1396f11093 100644 --- a/include/asm-sparc64/pbm.h +++ b/include/asm-sparc64/pbm.h @@ -139,6 +139,9 @@ struct pci_pbm_info { /* Opaque 32-bit system bus Port ID. */ u32 portid; + /* Opaque 32-bit handle used for hypervisor calls. */ + u32 devhandle; + /* Chipset version information. */ int chip_type; #define PBM_CHIP_TYPE_SABRE 1 -- cgit v1.2.2 From dedacf623283cb24933ec9f7d5bf539f19173cd4 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 9 Feb 2006 22:26:34 -0800 Subject: [SPARC64]: Add HV_PCI_TSBID() macro. For constructing hypervisor PCI TSB IDs. Signed-off-by: David S. Miller --- include/asm-sparc64/hypervisor.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'include') diff --git a/include/asm-sparc64/hypervisor.h b/include/asm-sparc64/hypervisor.h index b4e0d52acd..5d795ee519 100644 --- a/include/asm-sparc64/hypervisor.h +++ b/include/asm-sparc64/hypervisor.h @@ -1300,6 +1300,9 @@ struct hv_trap_trace_entry { * a tsbnum and a tsbindex. Bits 63:32 contain the * tsbnum and bits 31:00 contain the tsbindex. * + * Use the HV_PCI_TSBID() macro to construct such + * values. + * * io_attributes IO attributes for IOMMU mappings. One of more * of the attritbute bits are stores in a 64-bit * value. The values are defined below. @@ -1354,6 +1357,9 @@ struct hv_trap_trace_entry { (((d) & 0x1f) << 11) | \ (((f) & 0x07) << 8)) +#define HV_PCI_TSBID(__tsb_num, __tsb_index) \ + ((((u64)(__tsb_num)) << 32UL) | ((u64)(__tsb_index))) + #define HV_PCI_SYNC_FOR_DEVICE 0x01 #define HV_PCI_SYNC_FOR_CPU 0x02 -- cgit v1.2.2 From 12eaa328f9fb2d3fcb5afb682c762690d05a3cd8 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 10 Feb 2006 15:39:51 -0800 Subject: [SPARC64]: Use ASI_SCRATCHPAD address 0x0 properly. This is where the virtual address of the fault status area belongs. To set it up we don't make a hypervisor call, instead we call OBP's SUNW,set-trap-table with the real address of the fault status area as the second argument. And right before that call we write the virtual address into ASI_SCRATCHPAD vaddr 0x0. Signed-off-by: David S. Miller --- include/asm-sparc64/cpudata.h | 26 +++++++++++++------------- include/asm-sparc64/oplib.h | 1 + include/asm-sparc64/ttable.h | 34 +++++++++++++++++----------------- 3 files changed, 31 insertions(+), 30 deletions(-) (limited to 'include') diff --git a/include/asm-sparc64/cpudata.h b/include/asm-sparc64/cpudata.h index 338b0ca5b5..5a970f5ed9 100644 --- a/include/asm-sparc64/cpudata.h +++ b/include/asm-sparc64/cpudata.h @@ -156,13 +156,16 @@ extern struct sun4v_2insn_patch_entry __sun4v_2insn_patch, nop; \ .previous; -/* Clobbers TMP, current address space PGD phys address into DEST. */ -#define TRAP_LOAD_PGD_PHYS(DEST, TMP) \ +#define TRAP_LOAD_TRAP_BLOCK(DEST, TMP) \ __GET_CPUID(TMP) \ sethi %hi(trap_block), DEST; \ sllx TMP, TRAP_BLOCK_SZ_SHIFT, TMP; \ or DEST, %lo(trap_block), DEST; \ add DEST, TMP, DEST; \ + +/* Clobbers TMP, current address space PGD phys address into DEST. */ +#define TRAP_LOAD_PGD_PHYS(DEST, TMP) \ + TRAP_LOAD_TRAP_BLOCK(DEST, TMP) \ ldx [DEST + TRAP_PER_CPU_PGD_PADDR], DEST; /* Clobbers TMP, loads local processor's IRQ work area into DEST. */ @@ -175,11 +178,8 @@ extern struct sun4v_2insn_patch_entry __sun4v_2insn_patch, /* Clobbers TMP, loads DEST with current thread info pointer. */ #define TRAP_LOAD_THREAD_REG(DEST, TMP) \ - __GET_CPUID(TMP) \ - sethi %hi(trap_block), DEST; \ - sllx TMP, TRAP_BLOCK_SZ_SHIFT, TMP; \ - or DEST, %lo(trap_block), DEST; \ - ldx [DEST + TMP], DEST; + TRAP_LOAD_TRAP_BLOCK(DEST, TMP) \ + ldx [DEST + TRAP_PER_CPU_THREAD], DEST; /* Given the current thread info pointer in THR, load the per-cpu * area base of the current processor into DEST. REG1, REG2, and REG3 are @@ -201,13 +201,13 @@ extern struct sun4v_2insn_patch_entry __sun4v_2insn_patch, #else -#define __GET_CPUID(REG) \ - mov 0, REG; +#define TRAP_LOAD_TRAP_BLOCK(DEST, TMP) \ + sethi %hi(trap_block), DEST; \ + or DEST, %lo(trap_block), DEST; \ /* Uniprocessor versions, we know the cpuid is zero. */ #define TRAP_LOAD_PGD_PHYS(DEST, TMP) \ - sethi %hi(trap_block), DEST; \ - or DEST, %lo(trap_block), DEST; \ + TRAP_LOAD_TRAP_BLOCK(DEST, TMP) \ ldx [DEST + TRAP_PER_CPU_PGD_PADDR], DEST; #define TRAP_LOAD_IRQ_WORK(DEST, TMP) \ @@ -215,8 +215,8 @@ extern struct sun4v_2insn_patch_entry __sun4v_2insn_patch, or DEST, %lo(__irq_work), DEST; #define TRAP_LOAD_THREAD_REG(DEST, TMP) \ - sethi %hi(trap_block), DEST; \ - ldx [DEST + %lo(trap_block)], DEST; + TRAP_LOAD_TRAP_BLOCK(DEST, TMP) \ + ldx [DEST + TRAP_PER_CPU_THREAD], DEST; /* No per-cpu areas on uniprocessor, so no need to load DEST. */ #define LOAD_PER_CPU_BASE(DEST, THR, REG1, REG2, REG3) diff --git a/include/asm-sparc64/oplib.h b/include/asm-sparc64/oplib.h index 2ea545b931..ce5066ef2d 100644 --- a/include/asm-sparc64/oplib.h +++ b/include/asm-sparc64/oplib.h @@ -338,6 +338,7 @@ int cpu_find_by_mid(int mid, int *prom_node); /* Client interface level routines. */ extern void prom_set_trap_table(unsigned long tba); +extern void prom_set_trap_table_sun4v(unsigned long tba, unsigned long mmfsa); extern long p1275_cmd(const char *, long, ...); diff --git a/include/asm-sparc64/ttable.h b/include/asm-sparc64/ttable.h index 972f913709..6bb86a7a5b 100644 --- a/include/asm-sparc64/ttable.h +++ b/include/asm-sparc64/ttable.h @@ -180,25 +180,25 @@ #define KPROBES_TRAP(lvl) TRAP_ARG(bad_trap, lvl) #endif -#define SUN4V_ITSB_MISS \ - mov SCRATCHPAD_CPUID, %g1; \ - ldxa [%g1] ASI_SCRATCHPAD, %g2; \ - ldxa [%g1 + %g1] ASI_SCRATCHPAD, %g1;\ - sethi %hi(trap_block), %g5; \ - sllx %g2, TRAP_BLOCK_SZ_SHIFT, %g2; \ - or %g5, %lo(trap_block), %g5; \ - ba,pt %xcc, sun4v_itsb_miss; \ - add %g5, %g2, %g5; +#define SUN4V_ITSB_MISS \ + ldxa [%g0] ASI_SCRATCHPAD, %g2; \ + ldx [%g2 + HV_FAULT_I_ADDR_OFFSET], %g4; \ + ldx [%g2 + HV_FAULT_I_CTX_OFFSET], %g5; \ + srlx %g4, 22, %g7; \ + sllx %g5, 48, %g6; \ + brz,pn %g5, kvmap_itlb_4v; \ + or %g6, %g7, %g6; \ + ba,a,pt %xcc, sun4v_itsb_miss; #define SUN4V_DTSB_MISS \ - mov SCRATCHPAD_CPUID, %g1; \ - ldxa [%g1] ASI_SCRATCHPAD, %g2; \ - ldxa [%g1 + %g1] ASI_SCRATCHPAD, %g1;\ - sethi %hi(trap_block), %g5; \ - sllx %g2, TRAP_BLOCK_SZ_SHIFT, %g2; \ - or %g5, %lo(trap_block), %g5; \ - ba,pt %xcc, sun4v_dtsb_miss; \ - add %g5, %g2, %g5; + ldxa [%g0] ASI_SCRATCHPAD, %g2; \ + ldx [%g2 + HV_FAULT_D_ADDR_OFFSET], %g4; \ + ldx [%g2 + HV_FAULT_D_CTX_OFFSET], %g5; \ + srlx %g4, 22, %g7; \ + sllx %g5, 48, %g6; \ + brz,pn %g5, kvmap_dtlb_4v; \ + or %g6, %g7, %g6; \ + ba,a,pt %xcc, sun4v_dtsb_miss; /* Before touching these macros, you owe it to yourself to go and * see how arch/sparc64/kernel/winfixup.S works... -DaveM -- cgit v1.2.2 From 02fd473bd4844befc74f7ca67cd60891e0a2d890 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sat, 11 Feb 2006 02:25:21 -0800 Subject: [SPARC64]: Add SUN4V Hypervisor Console driver. Since it can do things like BREAK and HUP, we implement this as a serial uart driver. This still needs interrupt probing code, as I haven't figured out how interrupts will work or be probed for on SUN4V yet. Signed-off-by: David S. Miller --- include/linux/serial_core.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include') diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index 4041122dab..57abcea1cb 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -127,6 +127,9 @@ /* Hilscher netx */ #define PORT_NETX 71 +/* SUN4V Hypervisor Console */ +#define PORT_SUNHV 72 + #ifdef __KERNEL__ #include -- cgit v1.2.2 From 459b6e621e0e15315c25bac47fa7113e5818d45d Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sat, 11 Feb 2006 12:21:20 -0800 Subject: [SPARC64]: Fix some SUN4V TLB miss bugs. Code patching did not sign extend negative branch offsets correctly. Kernel TLB miss path needs patching and %g4 register preservation in order to handle SUN4V correctly. Signed-off-by: David S. Miller --- include/asm-sparc64/ttable.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'include') diff --git a/include/asm-sparc64/ttable.h b/include/asm-sparc64/ttable.h index 6bb86a7a5b..9e28b240f3 100644 --- a/include/asm-sparc64/ttable.h +++ b/include/asm-sparc64/ttable.h @@ -186,19 +186,19 @@ ldx [%g2 + HV_FAULT_I_CTX_OFFSET], %g5; \ srlx %g4, 22, %g7; \ sllx %g5, 48, %g6; \ - brz,pn %g5, kvmap_itlb_4v; \ + ba,pt %xcc, sun4v_itsb_miss; \ or %g6, %g7, %g6; \ - ba,a,pt %xcc, sun4v_itsb_miss; + nop; -#define SUN4V_DTSB_MISS \ +#define SUN4V_DTSB_MISS \ ldxa [%g0] ASI_SCRATCHPAD, %g2; \ ldx [%g2 + HV_FAULT_D_ADDR_OFFSET], %g4; \ ldx [%g2 + HV_FAULT_D_CTX_OFFSET], %g5; \ srlx %g4, 22, %g7; \ sllx %g5, 48, %g6; \ - brz,pn %g5, kvmap_dtlb_4v; \ + ba,pt %xcc, sun4v_dtsb_miss; \ or %g6, %g7, %g6; \ - ba,a,pt %xcc, sun4v_dtsb_miss; + nop; /* Before touching these macros, you owe it to yourself to go and * see how arch/sparc64/kernel/winfixup.S works... -DaveM -- cgit v1.2.2 From 490384e752a43aa281ed533e9de2da36df25c337 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sat, 11 Feb 2006 14:41:18 -0800 Subject: [SPARC64]: Register kernel TSB with hypervisor. We do this right after we take over the trap table from OBP. Signed-off-by: David S. Miller --- include/asm-sparc64/pgtable.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/asm-sparc64/pgtable.h b/include/asm-sparc64/pgtable.h index c42c06a37d..a480007f0a 100644 --- a/include/asm-sparc64/pgtable.h +++ b/include/asm-sparc64/pgtable.h @@ -438,6 +438,7 @@ extern unsigned long get_fb_unmapped_area(struct file *filp, unsigned long, extern void pgtable_cache_init(void); extern void sun4v_register_fault_status(void); +extern void sun4v_ktsb_register(void); #endif /* !(__ASSEMBLY__) */ -- cgit v1.2.2 From c4bce90ea2069e5a87beac806de3090ab32128d5 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sat, 11 Feb 2006 21:57:54 -0800 Subject: [SPARC64]: Deal with PTE layout differences in SUN4V. Yes, you heard it right, they changed the PTE layout for SUN4V. Ho hum... This is the simple and inefficient way to support this. It'll get optimized, don't worry. Signed-off-by: David S. Miller --- include/asm-sparc64/pgtable.h | 266 ++++++++++++------------------------------ 1 file changed, 72 insertions(+), 194 deletions(-) (limited to 'include') diff --git a/include/asm-sparc64/pgtable.h b/include/asm-sparc64/pgtable.h index a480007f0a..bd8bce704a 100644 --- a/include/asm-sparc64/pgtable.h +++ b/include/asm-sparc64/pgtable.h @@ -90,134 +90,48 @@ #endif /* !(__ASSEMBLY__) */ -/* Spitfire/Cheetah TTE bits. */ -#define _PAGE_VALID _AC(0x8000000000000000,UL) /* Valid TTE */ -#define _PAGE_R _AC(0x8000000000000000,UL) /* Keep ref bit up to date*/ -#define _PAGE_SZ4MB _AC(0x6000000000000000,UL) /* 4MB Page */ -#define _PAGE_SZ512K _AC(0x4000000000000000,UL) /* 512K Page */ -#define _PAGE_SZ64K _AC(0x2000000000000000,UL) /* 64K Page */ -#define _PAGE_SZ8K _AC(0x0000000000000000,UL) /* 8K Page */ -#define _PAGE_NFO _AC(0x1000000000000000,UL) /* No Fault Only */ -#define _PAGE_IE _AC(0x0800000000000000,UL) /* Invert Endianness */ -#define _PAGE_SOFT2 _AC(0x07FC000000000000,UL) /* Software bits, set 2 */ -#define _PAGE_RES1 _AC(0x0002000000000000,UL) /* Reserved */ -#define _PAGE_SZ32MB _AC(0x0001000000000000,UL) /* (Panther) 32MB page */ -#define _PAGE_SZ256MB _AC(0x2001000000000000,UL) /* (Panther) 256MB page */ -#define _PAGE_SN _AC(0x0000800000000000,UL) /* (Cheetah) Snoop */ -#define _PAGE_RES2 _AC(0x0000780000000000,UL) /* Reserved */ -#define _PAGE_PADDR_SF _AC(0x000001FFFFFFE000,UL) /* (Spitfire) paddr[40:13]*/ -#define _PAGE_PADDR _AC(0x000007FFFFFFE000,UL) /* (Cheetah) paddr[42:13] */ -#define _PAGE_SOFT _AC(0x0000000000001F80,UL) /* Software bits */ -#define _PAGE_L _AC(0x0000000000000040,UL) /* Locked TTE */ -#define _PAGE_CP _AC(0x0000000000000020,UL) /* Cacheable in P-Cache */ -#define _PAGE_CV _AC(0x0000000000000010,UL) /* Cacheable in V-Cache */ -#define _PAGE_E _AC(0x0000000000000008,UL) /* side-Effect */ -#define _PAGE_P _AC(0x0000000000000004,UL) /* Privileged Page */ -#define _PAGE_W _AC(0x0000000000000002,UL) /* Writable */ -#define _PAGE_G _AC(0x0000000000000001,UL) /* Global */ - -#define _PAGE_ALL_SZ_BITS \ - (_PAGE_SZ4MB | _PAGE_SZ512K | _PAGE_SZ64K | \ - _PAGE_SZ8K | _PAGE_SZ32MB | _PAGE_SZ256MB) - -/* Here are the SpitFire software bits we use in the TTE's. - * - * WARNING: If you are going to try and start using some - * of the soft2 bits, you will need to make - * modifications to the swap entry implementation. - * For example, one thing that could happen is that - * swp_entry_to_pte() would BUG_ON() if you tried - * to use one of the soft2 bits for _PAGE_FILE. - * - * Like other architectures, I have aliased _PAGE_FILE with - * _PAGE_MODIFIED. This works because _PAGE_FILE is never - * interpreted that way unless _PAGE_PRESENT is clear. - */ -#define _PAGE_EXEC _AC(0x0000000000001000,UL) /* Executable SW bit */ -#define _PAGE_MODIFIED _AC(0x0000000000000800,UL) /* Modified (dirty) */ -#define _PAGE_FILE _AC(0x0000000000000800,UL) /* Pagecache page */ -#define _PAGE_ACCESSED _AC(0x0000000000000400,UL) /* Accessed (ref'd) */ -#define _PAGE_READ _AC(0x0000000000000200,UL) /* Readable SW Bit */ -#define _PAGE_WRITE _AC(0x0000000000000100,UL) /* Writable SW Bit */ -#define _PAGE_PRESENT _AC(0x0000000000000080,UL) /* Present */ - -#if PAGE_SHIFT == 13 -#define _PAGE_SZBITS _PAGE_SZ8K -#elif PAGE_SHIFT == 16 -#define _PAGE_SZBITS _PAGE_SZ64K -#elif PAGE_SHIFT == 19 -#define _PAGE_SZBITS _PAGE_SZ512K -#elif PAGE_SHIFT == 22 -#define _PAGE_SZBITS _PAGE_SZ4MB -#else -#error Wrong PAGE_SHIFT specified -#endif - -#if defined(CONFIG_HUGETLB_PAGE_SIZE_4MB) -#define _PAGE_SZHUGE _PAGE_SZ4MB -#elif defined(CONFIG_HUGETLB_PAGE_SIZE_512K) -#define _PAGE_SZHUGE _PAGE_SZ512K -#elif defined(CONFIG_HUGETLB_PAGE_SIZE_64K) -#define _PAGE_SZHUGE _PAGE_SZ64K -#endif - -#define _PAGE_CACHE (_PAGE_CP | _PAGE_CV) - -#define __DIRTY_BITS (_PAGE_MODIFIED | _PAGE_WRITE | _PAGE_W) -#define __ACCESS_BITS (_PAGE_ACCESSED | _PAGE_READ | _PAGE_R) -#define __PRIV_BITS _PAGE_P - -#define PAGE_NONE __pgprot (_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_CACHE) - -/* Don't set the TTE _PAGE_W bit here, else the dirty bit never gets set. */ -#define PAGE_SHARED __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \ - __ACCESS_BITS | _PAGE_WRITE | _PAGE_EXEC) - -#define PAGE_COPY __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \ - __ACCESS_BITS | _PAGE_EXEC) - -#define PAGE_READONLY __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \ - __ACCESS_BITS | _PAGE_EXEC) - -#define PAGE_KERNEL __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \ - __PRIV_BITS | \ - __ACCESS_BITS | __DIRTY_BITS | _PAGE_EXEC) - -#define PAGE_SHARED_NOEXEC __pgprot (_PAGE_PRESENT | _PAGE_VALID | \ - _PAGE_CACHE | \ - __ACCESS_BITS | _PAGE_WRITE) - -#define PAGE_COPY_NOEXEC __pgprot (_PAGE_PRESENT | _PAGE_VALID | \ - _PAGE_CACHE | __ACCESS_BITS) - -#define PAGE_READONLY_NOEXEC __pgprot (_PAGE_PRESENT | _PAGE_VALID | \ - _PAGE_CACHE | __ACCESS_BITS) - -#define _PFN_MASK _PAGE_PADDR - -#define pg_iobits (_PAGE_VALID | _PAGE_PRESENT | __DIRTY_BITS | \ - __ACCESS_BITS | _PAGE_E) - -#define __P000 PAGE_NONE -#define __P001 PAGE_READONLY_NOEXEC -#define __P010 PAGE_COPY_NOEXEC -#define __P011 PAGE_COPY_NOEXEC -#define __P100 PAGE_READONLY -#define __P101 PAGE_READONLY -#define __P110 PAGE_COPY -#define __P111 PAGE_COPY - -#define __S000 PAGE_NONE -#define __S001 PAGE_READONLY_NOEXEC -#define __S010 PAGE_SHARED_NOEXEC -#define __S011 PAGE_SHARED_NOEXEC -#define __S100 PAGE_READONLY -#define __S101 PAGE_READONLY -#define __S110 PAGE_SHARED -#define __S111 PAGE_SHARED +/* PTE bits which are the same in SUN4U and SUN4V format. */ +#define _PAGE_VALID 0x8000000000000000 /* Valid TTE */ +#define _PAGE_R 0x8000000000000000 /* Keep ref bit up to date*/ + +/* These are actually filled in at boot time by sun4{u,v}_pgprot_init() */ +#define __P000 __pgprot(0) +#define __P001 __pgprot(0) +#define __P010 __pgprot(0) +#define __P011 __pgprot(0) +#define __P100 __pgprot(0) +#define __P101 __pgprot(0) +#define __P110 __pgprot(0) +#define __P111 __pgprot(0) + +#define __S000 __pgprot(0) +#define __S001 __pgprot(0) +#define __S010 __pgprot(0) +#define __S011 __pgprot(0) +#define __S100 __pgprot(0) +#define __S101 __pgprot(0) +#define __S110 __pgprot(0) +#define __S111 __pgprot(0) #ifndef __ASSEMBLY__ +extern pte_t mk_pte_io(unsigned long, pgprot_t, int, unsigned long); + +extern unsigned long pte_sz_bits(unsigned long size); + +extern pgprot_t PAGE_KERNEL; +extern pgprot_t PAGE_KERNEL_LOCKED; +extern pgprot_t PAGE_COPY; + +/* XXX This uglyness is for the atyfb driver's sparc mmap() support. XXX */ +extern unsigned long _PAGE_IE; +extern unsigned long _PAGE_E; +extern unsigned long _PAGE_CACHE; + +extern unsigned long pg_iobits; +extern unsigned long _PAGE_ALL_SZ_BITS; +extern unsigned long _PAGE_SZBITS; + extern unsigned long phys_base; extern unsigned long pfn_base; @@ -229,27 +143,12 @@ extern struct page *mem_map_zero; * the first physical page in the machine is at some huge physical address, * such as 4GB. This is common on a partitioned E10000, for example. */ - -#define pfn_pte(pfn, prot) \ - __pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot) | _PAGE_SZBITS) +extern pte_t pfn_pte(unsigned long, pgprot_t); #define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot)) +extern unsigned long pte_pfn(pte_t); +#define pte_page(x) pfn_to_page(pte_pfn(x)) +extern pte_t pte_modify(pte_t, pgprot_t); -#define pte_pfn(x) ((pte_val(x) & _PAGE_PADDR)>>PAGE_SHIFT) -#define pte_page(x) pfn_to_page(pte_pfn(x)) - -static inline pte_t pte_modify(pte_t orig_pte, pgprot_t new_prot) -{ - pte_t __pte; - const unsigned long preserve_mask = (_PFN_MASK | - _PAGE_MODIFIED | _PAGE_ACCESSED | - _PAGE_CACHE | _PAGE_E | - _PAGE_PRESENT | _PAGE_SZBITS); - - pte_val(__pte) = (pte_val(orig_pte) & preserve_mask) | - (pgprot_val(new_prot) & ~preserve_mask); - - return __pte; -} #define pmd_set(pmdp, ptep) \ (pmd_val(*(pmdp)) = (__pa((unsigned long) (ptep)) >> 11UL)) #define pud_set(pudp, pmdp) \ @@ -259,8 +158,6 @@ static inline pte_t pte_modify(pte_t orig_pte, pgprot_t new_prot) #define pmd_page(pmd) virt_to_page((void *)__pmd_page(pmd)) #define pud_page(pud) \ ((unsigned long) __va((((unsigned long)pud_val(pud))<<11UL))) -#define pte_none(pte) (!pte_val(pte)) -#define pte_present(pte) (pte_val(pte) & _PAGE_PRESENT) #define pmd_none(pmd) (!pmd_val(pmd)) #define pmd_bad(pmd) (0) #define pmd_present(pmd) (pmd_val(pmd) != 0U) @@ -270,30 +167,29 @@ static inline pte_t pte_modify(pte_t orig_pte, pgprot_t new_prot) #define pud_present(pud) (pud_val(pud) != 0U) #define pud_clear(pudp) (pud_val(*(pudp)) = 0U) +/* Same in both SUN4V and SUN4U. */ +#define pte_none(pte) (!pte_val(pte)) + +extern unsigned long pte_present(pte_t); + /* The following only work if pte_present() is true. * Undefined behaviour if not.. */ -#define pte_read(pte) (pte_val(pte) & _PAGE_READ) -#define pte_exec(pte) (pte_val(pte) & _PAGE_EXEC) -#define pte_write(pte) (pte_val(pte) & _PAGE_WRITE) -#define pte_dirty(pte) (pte_val(pte) & _PAGE_MODIFIED) -#define pte_young(pte) (pte_val(pte) & _PAGE_ACCESSED) -#define pte_wrprotect(pte) (__pte(pte_val(pte) & ~(_PAGE_WRITE|_PAGE_W))) -#define pte_rdprotect(pte) \ - (__pte(((pte_val(pte)<<1UL)>>1UL) & ~_PAGE_READ)) -#define pte_mkclean(pte) \ - (__pte(pte_val(pte) & ~(_PAGE_MODIFIED|_PAGE_W))) -#define pte_mkold(pte) \ - (__pte(((pte_val(pte)<<1UL)>>1UL) & ~_PAGE_ACCESSED)) - -/* Permanent address of a page. */ -#define __page_address(page) page_address(page) +extern unsigned long pte_read(pte_t); +extern unsigned long pte_exec(pte_t); +extern unsigned long pte_write(pte_t); +extern unsigned long pte_dirty(pte_t); +extern unsigned long pte_young(pte_t); +extern pte_t pte_wrprotect(pte_t); +extern pte_t pte_rdprotect(pte_t); +extern pte_t pte_mkclean(pte_t); +extern pte_t pte_mkold(pte_t); /* Be very careful when you change these three, they are delicate. */ -#define pte_mkyoung(pte) (__pte(pte_val(pte) | _PAGE_ACCESSED | _PAGE_R)) -#define pte_mkwrite(pte) (__pte(pte_val(pte) | _PAGE_WRITE)) -#define pte_mkdirty(pte) (__pte(pte_val(pte) | _PAGE_MODIFIED | _PAGE_W)) -#define pte_mkhuge(pte) (__pte(pte_val(pte) | _PAGE_SZHUGE)) +extern pte_t pte_mkyoung(pte_t); +extern pte_t pte_mkwrite(pte_t); +extern pte_t pte_mkdirty(pte_t); +extern pte_t pte_mkhuge(pte_t); /* to find an entry in a page-table-directory. */ #define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1)) @@ -328,6 +224,9 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *p /* It is more efficient to let flush_tlb_kernel_range() * handle init_mm tlb flushes. + * + * SUN4V NOTE: _PAGE_VALID is the same value in both the SUN4U + * and SUN4V pte layout, so this inline test is fine. */ if (likely(mm != &init_mm) && (pte_val(orig) & _PAGE_VALID)) tlb_batch_add(mm, addr, ptep, orig); @@ -362,42 +261,23 @@ extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t); #define __swp_entry_to_pte(x) ((pte_t) { (x).val }) /* File offset in PTE support. */ -#define pte_file(pte) (pte_val(pte) & _PAGE_FILE) +extern unsigned long pte_file(pte_t); #define pte_to_pgoff(pte) (pte_val(pte) >> PAGE_SHIFT) -#define pgoff_to_pte(off) (__pte(((off) << PAGE_SHIFT) | _PAGE_FILE)) +extern pte_t pgoff_to_pte(unsigned long); #define PTE_FILE_MAX_BITS (64UL - PAGE_SHIFT - 1UL) extern unsigned long prom_virt_to_phys(unsigned long, int *); -static __inline__ unsigned long -sun4u_get_pte (unsigned long addr) -{ - pgd_t *pgdp; - pud_t *pudp; - pmd_t *pmdp; - pte_t *ptep; - - if (addr >= PAGE_OFFSET) - return addr & _PAGE_PADDR; - if ((addr >= LOW_OBP_ADDRESS) && (addr < HI_OBP_ADDRESS)) - return prom_virt_to_phys(addr, NULL); - pgdp = pgd_offset_k(addr); - pudp = pud_offset(pgdp, addr); - pmdp = pmd_offset(pudp, addr); - ptep = pte_offset_kernel(pmdp, addr); - return pte_val(*ptep) & _PAGE_PADDR; -} +extern unsigned long sun4u_get_pte(unsigned long); -static __inline__ unsigned long -__get_phys (unsigned long addr) +static inline unsigned long __get_phys(unsigned long addr) { - return sun4u_get_pte (addr); + return sun4u_get_pte(addr); } -static __inline__ int -__get_iospace (unsigned long addr) +static inline int __get_iospace(unsigned long addr) { - return ((sun4u_get_pte (addr) & 0xf0000000) >> 28); + return ((sun4u_get_pte(addr) & 0xf0000000) >> 28); } extern unsigned long *sparc64_valid_addr_bitmap; @@ -411,9 +291,7 @@ extern int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long from, unsigned long size, pgprot_t prot); /* Clear virtual and physical cachability, set side-effect bit. */ -#define pgprot_noncached(prot) \ - (__pgprot((pgprot_val(prot) & ~(_PAGE_CP | _PAGE_CV)) | \ - _PAGE_E)) +extern pgprot_t pgprot_noncached(pgprot_t); /* * For sparc32&64, the pfn in io_remap_pfn_range() carries in -- cgit v1.2.2 From 1a7a242c898dd131f2df005c492e9b44fb8900e0 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sat, 11 Feb 2006 23:24:30 -0800 Subject: [SPARC64]: Recognize "virtual-console" as input and output console device. Signed-off-by: David S. Miller --- include/asm-sparc/oplib.h | 2 ++ include/asm-sparc64/oplib.h | 2 ++ 2 files changed, 4 insertions(+) (limited to 'include') diff --git a/include/asm-sparc/oplib.h b/include/asm-sparc/oplib.h index d0d76b30eb..f283f8aaf6 100644 --- a/include/asm-sparc/oplib.h +++ b/include/asm-sparc/oplib.h @@ -165,6 +165,7 @@ enum prom_input_device { PROMDEV_ITTYA, /* input from ttya */ PROMDEV_ITTYB, /* input from ttyb */ PROMDEV_IRSC, /* input from rsc */ + PROMDEV_IVCONS, /* input from virtual-console */ PROMDEV_I_UNK, }; @@ -177,6 +178,7 @@ enum prom_output_device { PROMDEV_OTTYA, /* to ttya */ PROMDEV_OTTYB, /* to ttyb */ PROMDEV_ORSC, /* to rsc */ + PROMDEV_OVCONS, /* to virtual-console */ PROMDEV_O_UNK, }; diff --git a/include/asm-sparc64/oplib.h b/include/asm-sparc64/oplib.h index ce5066ef2d..0631d13475 100644 --- a/include/asm-sparc64/oplib.h +++ b/include/asm-sparc64/oplib.h @@ -167,6 +167,7 @@ enum prom_input_device { PROMDEV_ITTYA, /* input from ttya */ PROMDEV_ITTYB, /* input from ttyb */ PROMDEV_IRSC, /* input from rsc */ + PROMDEV_IVCONS, /* input from virtual-console */ PROMDEV_I_UNK, }; @@ -179,6 +180,7 @@ enum prom_output_device { PROMDEV_OTTYA, /* to ttya */ PROMDEV_OTTYB, /* to ttyb */ PROMDEV_ORSC, /* to rsc */ + PROMDEV_OVCONS, /* to virtual-console */ PROMDEV_O_UNK, }; -- cgit v1.2.2 From ff02e0d26f139ad95ec3a7e94f88faccaa180dff Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 12 Feb 2006 17:07:51 -0800 Subject: [SPARC64]: Move PTE field definitions back into asm/pgtable.h Signed-off-by: David S. Miller --- include/asm-sparc64/pgtable.h | 88 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 86 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/asm-sparc64/pgtable.h b/include/asm-sparc64/pgtable.h index bd8bce704a..3c02d5d9a5 100644 --- a/include/asm-sparc64/pgtable.h +++ b/include/asm-sparc64/pgtable.h @@ -91,8 +91,92 @@ #endif /* !(__ASSEMBLY__) */ /* PTE bits which are the same in SUN4U and SUN4V format. */ -#define _PAGE_VALID 0x8000000000000000 /* Valid TTE */ -#define _PAGE_R 0x8000000000000000 /* Keep ref bit up to date*/ +#define _PAGE_VALID _AC(0x8000000000000000,UL) /* Valid TTE */ +#define _PAGE_R _AC(0x8000000000000000,UL) /* Keep ref bit uptodate*/ + +/* SUN4U pte bits... */ +#define _PAGE_SZ4MB_4U _AC(0x6000000000000000,UL) /* 4MB Page */ +#define _PAGE_SZ512K_4U _AC(0x4000000000000000,UL) /* 512K Page */ +#define _PAGE_SZ64K_4U _AC(0x2000000000000000,UL) /* 64K Page */ +#define _PAGE_SZ8K_4U _AC(0x0000000000000000,UL) /* 8K Page */ +#define _PAGE_NFO_4U _AC(0x1000000000000000,UL) /* No Fault Only */ +#define _PAGE_IE_4U _AC(0x0800000000000000,UL) /* Invert Endianness */ +#define _PAGE_SOFT2_4U _AC(0x07FC000000000000,UL) /* Software bits, set 2 */ +#define _PAGE_RES1_4U _AC(0x0002000000000000,UL) /* Reserved */ +#define _PAGE_SZ32MB_4U _AC(0x0001000000000000,UL) /* (Panther) 32MB page */ +#define _PAGE_SZ256MB_4U _AC(0x2001000000000000,UL) /* (Panther) 256MB page */ +#define _PAGE_SN_4U _AC(0x0000800000000000,UL) /* (Cheetah) Snoop */ +#define _PAGE_RES2_4U _AC(0x0000780000000000,UL) /* Reserved */ +#define _PAGE_PADDR_4U _AC(0x000007FFFFFFE000,UL) /* (Cheetah) pa[42:13] */ +#define _PAGE_SOFT_4U _AC(0x0000000000001F80,UL) /* Software bits: */ +#define _PAGE_EXEC_4U _AC(0x0000000000001000,UL) /* Executable SW bit */ +#define _PAGE_MODIFIED_4U _AC(0x0000000000000800,UL) /* Modified (dirty) */ +#define _PAGE_FILE_4U _AC(0x0000000000000800,UL) /* Pagecache page */ +#define _PAGE_ACCESSED_4U _AC(0x0000000000000400,UL) /* Accessed (ref'd) */ +#define _PAGE_READ_4U _AC(0x0000000000000200,UL) /* Readable SW Bit */ +#define _PAGE_WRITE_4U _AC(0x0000000000000100,UL) /* Writable SW Bit */ +#define _PAGE_PRESENT_4U _AC(0x0000000000000080,UL) /* Present */ +#define _PAGE_L_4U _AC(0x0000000000000040,UL) /* Locked TTE */ +#define _PAGE_CP_4U _AC(0x0000000000000020,UL) /* Cacheable in P-Cache */ +#define _PAGE_CV_4U _AC(0x0000000000000010,UL) /* Cacheable in V-Cache */ +#define _PAGE_E_4U _AC(0x0000000000000008,UL) /* side-Effect */ +#define _PAGE_P_4U _AC(0x0000000000000004,UL) /* Privileged Page */ +#define _PAGE_W_4U _AC(0x0000000000000002,UL) /* Writable */ + +/* SUN4V pte bits... */ +#define _PAGE_NFO_4V _AC(0x4000000000000000,UL) /* No Fault Only */ +#define _PAGE_SOFT2_4V _AC(0x3F00000000000000,UL) /* Software bits, set 2 */ +#define _PAGE_MODIFIED_4V _AC(0x2000000000000000,UL) /* Modified (dirty) */ +#define _PAGE_ACCESSED_4V _AC(0x1000000000000000,UL) /* Accessed (ref'd) */ +#define _PAGE_READ_4V _AC(0x0800000000000000,UL) /* Readable SW Bit */ +#define _PAGE_WRITE_4V _AC(0x0400000000000000,UL) /* Writable SW Bit */ +#define _PAGE_PADDR_4V _AC(0x00FFFFFFFFFFE000,UL) /* paddr[55:13] */ +#define _PAGE_IE_4V _AC(0x0000000000001000,UL) /* Invert Endianness */ +#define _PAGE_E_4V _AC(0x0000000000000800,UL) /* side-Effect */ +#define _PAGE_CP_4V _AC(0x0000000000000400,UL) /* Cacheable in P-Cache */ +#define _PAGE_CV_4V _AC(0x0000000000000200,UL) /* Cacheable in V-Cache */ +#define _PAGE_P_4V _AC(0x0000000000000100,UL) /* Privileged Page */ +#define _PAGE_EXEC_4V _AC(0x0000000000000080,UL) /* Executable Page */ +#define _PAGE_W_4V _AC(0x0000000000000040,UL) /* Writable */ +#define _PAGE_SOFT_4V _AC(0x0000000000000030,UL) /* Software bits */ +#define _PAGE_FILE_4V _AC(0x0000000000000020,UL) /* Pagecache page */ +#define _PAGE_PRESENT_4V _AC(0x0000000000000010,UL) /* Present */ +#define _PAGE_RESV_4V _AC(0x0000000000000008,UL) /* Reserved */ +#define _PAGE_SZ16GB_4V _AC(0x0000000000000007,UL) /* 16GB Page */ +#define _PAGE_SZ2GB_4V _AC(0x0000000000000006,UL) /* 2GB Page */ +#define _PAGE_SZ256MB_4V _AC(0x0000000000000005,UL) /* 256MB Page */ +#define _PAGE_SZ32MB_4V _AC(0x0000000000000004,UL) /* 32MB Page */ +#define _PAGE_SZ4MB_4V _AC(0x0000000000000003,UL) /* 4MB Page */ +#define _PAGE_SZ512K_4V _AC(0x0000000000000002,UL) /* 512K Page */ +#define _PAGE_SZ64K_4V _AC(0x0000000000000001,UL) /* 64K Page */ +#define _PAGE_SZ8K_4V _AC(0x0000000000000000,UL) /* 8K Page */ + +#if PAGE_SHIFT == 13 +#define _PAGE_SZBITS_4U _PAGE_SZ8K_4U +#define _PAGE_SZBITS_4V _PAGE_SZ8K_4V +#elif PAGE_SHIFT == 16 +#define _PAGE_SZBITS_4U _PAGE_SZ64K_4U +#define _PAGE_SZBITS_4V _PAGE_SZ64K_4V +#elif PAGE_SHIFT == 19 +#define _PAGE_SZBITS_4U _PAGE_SZ512K_4U +#define _PAGE_SZBITS_4V _PAGE_SZ512K_4V +#elif PAGE_SHIFT == 22 +#define _PAGE_SZBITS_4U _PAGE_SZ4MB_4U +#define _PAGE_SZBITS_4V _PAGE_SZ4MB_4V +#else +#error Wrong PAGE_SHIFT specified +#endif + +#if defined(CONFIG_HUGETLB_PAGE_SIZE_4MB) +#define _PAGE_SZHUGE_4U _PAGE_SZ4MB_4U +#define _PAGE_SZHUGE_4V _PAGE_SZ4MB_4V +#elif defined(CONFIG_HUGETLB_PAGE_SIZE_512K) +#define _PAGE_SZHUGE_4U _PAGE_SZ512K_4U +#define _PAGE_SZHUGE_4V _PAGE_SZ512K_4V +#elif defined(CONFIG_HUGETLB_PAGE_SIZE_64K) +#define _PAGE_SZHUGE_4U _PAGE_SZ64K_4U +#define _PAGE_SZHUGE_4V _PAGE_SZ64K_4V +#endif /* These are actually filled in at boot time by sun4{u,v}_pgprot_init() */ #define __P000 __pgprot(0) -- cgit v1.2.2 From cf627156c450cd5a0741b31f55181db3400d4887 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 12 Feb 2006 21:10:07 -0800 Subject: [SPARC64]: Use inline patching for critical PTE operations. This handles the SUN4U vs SUN4V PTE layout differences with near zero performance cost. Signed-off-by: David S. Miller --- include/asm-sparc64/pgtable.h | 488 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 485 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/asm-sparc64/pgtable.h b/include/asm-sparc64/pgtable.h index 3c02d5d9a5..00eecbb52f 100644 --- a/include/asm-sparc64/pgtable.h +++ b/include/asm-sparc64/pgtable.h @@ -227,11 +227,493 @@ extern struct page *mem_map_zero; * the first physical page in the machine is at some huge physical address, * such as 4GB. This is common on a partitioned E10000, for example. */ -extern pte_t pfn_pte(unsigned long, pgprot_t); +static inline pte_t pfn_pte(unsigned long pfn, pgprot_t prot) +{ + unsigned long paddr = pfn << PAGE_SHIFT; + unsigned long sz_bits; + + BUILD_BUG_ON(!__builtin_constant_p(_PAGE_SZBITS_4U) || + !__builtin_constant_p(_PAGE_SZBITS_4V)); + + sz_bits = 0UL; + if (_PAGE_SZBITS_4U != 0UL || _PAGE_SZBITS_4V != 0UL) { + BUILD_BUG_ON((_PAGE_SZBITS_4U & ~(0xfffffc0000000000UL)) || + (_PAGE_SZBITS_4V & ~(0x0000000000000fffUL))); + __asm__ __volatile__( + "\n661: sethi %uhi(%1), %0\n" + " sllx %0, 32, %0\n" + " .section .sun4v_2insn_patch, \"ax\"\n" + " .word 661b\n" + " mov %2, %0\n" + " nop\n" + " .previous\n" + : "=r" (sz_bits) + : "i" (_PAGE_SZBITS_4U), "i" (_PAGE_SZBITS_4V)); + } + return __pte(paddr | sz_bits | pgprot_val(prot)); +} #define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot)) -extern unsigned long pte_pfn(pte_t); + +/* This one can be done with two shifts. */ +static inline unsigned long pte_pfn(pte_t pte) +{ + const unsigned long pte_paddr_shl_sun4u = 21; + const unsigned long pte_paddr_shr_sun4u = 21 + PAGE_SHIFT; + const unsigned long pte_paddr_shl_sun4v = 8; + const unsigned long pte_paddr_shr_sun4v = 8 + PAGE_SHIFT; + unsigned long ret; + + __asm__ __volatile__( + "\n661: sllx %1, %2, %0\n" + " srlx %0, %3, %0\n" + " .section .sun4v_2insn_patch, \"ax\"\n" + " .word 661b\n" + " sllx %1, %4, %0\n" + " srlx %0, %5, %0\n" + " .previous\n" + : "=r" (ret) + : "r" (pte_val(pte)), + "i" (pte_paddr_shl_sun4u), "i" (pte_paddr_shr_sun4u), + "i" (pte_paddr_shl_sun4v), "i" (pte_paddr_shr_sun4v)); + + return ret; +} #define pte_page(x) pfn_to_page(pte_pfn(x)) -extern pte_t pte_modify(pte_t, pgprot_t); + +static inline pte_t pte_modify(pte_t pte, pgprot_t prot) +{ + const unsigned long preserve_mask_sun4u = (_PAGE_PADDR_4U | + _PAGE_MODIFIED_4U | + _PAGE_ACCESSED_4U | + _PAGE_CP_4U | + _PAGE_CV_4U | + _PAGE_E_4U | + _PAGE_PRESENT_4U | + _PAGE_SZBITS_4U); + const unsigned long preserve_mask_sun4v = (_PAGE_PADDR_4V | + _PAGE_MODIFIED_4V | + _PAGE_ACCESSED_4V | + _PAGE_CP_4V | + _PAGE_CV_4V | + _PAGE_E_4V | + _PAGE_PRESENT_4V | + _PAGE_SZBITS_4V); + unsigned long mask, tmp; + + /* SUN4U: 0x600307ffffffecb8 (negated == 0x9ffcf80000001347) + * SUN4V: 0x30ffffffffffee17 (negated == 0xcf000000000011e8) + * + * Even if we use negation tricks the result is still a 6 + * instruction sequence, so don't try to play fancy and just + * do the most straightforward implementation. + * + * Note: We encode this into 3 sun4v 2-insn patch sequences. + */ + + __asm__ __volatile__( + "\n661: sethi %%uhi(%2), %1\n" + " sethi %%hi(%2), %0\n" + "\n662: or %1, %%ulo(%2), %1\n" + " or %0, %%lo(%2), %0\n" + "\n663: sllx %1, 32, %1\n" + " or %0, %1, %0\n" + " .section .sun4v_2insn_patch, \"ax\"\n" + " .word 661b\n" + " sethi %%uhi(%3), %1\n" + " sethi %%hi(%3), %0\n" + " .word 662b\n" + " or %1, %%ulo(%3), %1\n" + " or %0, %%lo(%3), %0\n" + " .word 663b\n" + " sllx %1, 32, %1\n" + " or %0, %1, %0\n" + " .previous\n" + : "=r" (mask), "=r" (tmp) + : "i" (preserve_mask_sun4u), "i" (preserve_mask_sun4v)); + + return __pte((pte_val(pte) & mask) | (pgprot_val(prot) & ~mask)); +} + +static inline pte_t pgoff_to_pte(unsigned long off) +{ + off <<= PAGE_SHIFT; + + BUILD_BUG_ON((_PAGE_FILE_4U & ~0xfffUL) || + (_PAGE_FILE_4V & ~0xfffUL)); + + __asm__ __volatile__( + "\n661: or %0, %2, %0\n" + " .section .sun4v_1insn_patch, \"ax\"\n" + " .word 661b\n" + " or %0, %3, %0\n" + " .previous\n" + : "=r" (off) + : "0" (off), "i" (_PAGE_FILE_4U), "i" (_PAGE_FILE_4V)); + + return __pte(off); +} + +static inline pgprot_t pgprot_noncached(pgprot_t prot) +{ + unsigned long val = pgprot_val(prot); + + BUILD_BUG_ON(((_PAGE_CP_4U | _PAGE_CP_4U | _PAGE_E_4U) & ~(0xfffUL)) || + ((_PAGE_CP_4V | _PAGE_CP_4V | _PAGE_E_4V) & ~(0xfffUL))); + + __asm__ __volatile__( + "\n661: andn %0, %2, %0\n" + " or %0, %3, %0\n" + " .section .sun4v_2insn_patch, \"ax\"\n" + " .word 661b\n" + " andn %0, %4, %0\n" + " or %0, %3, %0\n" + " .previous\n" + : "=r" (val) + : "0" (val), "i" (_PAGE_CP_4U | _PAGE_CV_4U), "i" (_PAGE_E_4U), + "i" (_PAGE_CP_4V | _PAGE_CV_4V), "i" (_PAGE_E_4V)); + + return __pgprot(val); +} +/* Various pieces of code check for platform support by ifdef testing + * on "pgprot_noncached". That's broken and should be fixed, but for + * now... + */ +#define pgprot_noncached pgprot_noncached + +static inline pte_t pte_mkhuge(pte_t pte) +{ + const unsigned long mask_4u = _PAGE_SZHUGE_4U; + const unsigned long mask_4v = _PAGE_SZHUGE_4V; + unsigned long mask; + + BUILD_BUG_ON((mask_4u & ~(0xfffffc0000000000UL)) || + (mask_4v & ~(0xfffUL))); + + __asm__ __volatile__( + "\n661: sethi %%uhi(%1), %0\n" + " sllx %0, 32, %0\n" + " .section .sun4v_2insn_patch, \"ax\"\n" + " .word 661b\n" + " mov %2, %0\n" + " nop\n" + " .previous\n" + : "=r" (mask) + : "i" (mask_4u), "i" (mask_4v)); + + return __pte(pte_val(pte) | mask); +} + +static inline pte_t pte_mkdirty(pte_t pte) +{ + const unsigned long mask_4u = _PAGE_MODIFIED_4U | _PAGE_W_4U; + const unsigned long mask_4v = _PAGE_MODIFIED_4V | _PAGE_W_4V; + unsigned long val = pte_val(pte), tmp; + + BUILD_BUG_ON((mask_4u & ~(0x0000000000000fffUL)) || + (mask_4v & ~(0xfffffc0000000fffUL))); + + __asm__ __volatile__( + "\n661: or %0, %3, %0\n" + " nop\n" + "\n662: nop\n" + " nop\n" + " .section .sun4v_2insn_patch, \"ax\"\n" + " .word 661b\n" + " sethi %%uhi(%4), %1\n" + " sllx %1, 32, %1\n" + " .word 662b\n" + " or %1, %%lo(%4), %1\n" + " or %0, %1, %0\n" + " .previous\n" + : "=r" (val), "=r" (tmp) + : "0" (val), "i" (mask_4u), "i" (mask_4v)); + + return __pte(val); +} + +static inline pte_t pte_mkclean(pte_t pte) +{ + const unsigned long mask_4u = _PAGE_MODIFIED_4U | _PAGE_W_4U; + const unsigned long mask_4v = _PAGE_MODIFIED_4V | _PAGE_W_4V; + unsigned long val = pte_val(pte), tmp; + + BUILD_BUG_ON((mask_4u & ~(0x0000000000000fffUL)) || + (mask_4v & ~(0xfffffc0000000fffUL))); + + __asm__ __volatile__( + "\n661: andn %0, %3, %0\n" + " nop\n" + "\n662: nop\n" + " nop\n" + " .section .sun4v_2insn_patch, \"ax\"\n" + " .word 661b\n" + " sethi %%uhi(%4), %1\n" + " sllx %1, 32, %1\n" + " .word 662b\n" + " or %1, %%lo(%4), %1\n" + " andn %0, %1, %0\n" + " .previous\n" + : "=r" (val), "=r" (tmp) + : "0" (val), "i" (mask_4u), "i" (mask_4v)); + + return __pte(val); +} + +static inline pte_t pte_mkwrite(pte_t pte) +{ + const unsigned long mask_4u = _PAGE_WRITE_4U; + const unsigned long mask_4v = _PAGE_WRITE_4V; + unsigned long val = pte_val(pte), mask; + + BUILD_BUG_ON((mask_4u & ~(0x0000000000000fffUL)) || + (mask_4v & ~(0xfffffc0000000000UL))); + + __asm__ __volatile__( + "\n661: mov %1, %0\n" + " nop\n" + " .section .sun4v_2insn_patch, \"ax\"\n" + " .word 661b\n" + " sethi %%uhi(%2), %0\n" + " sllx %0, 32, %0\n" + " .previous\n" + : "=r" (mask) + : "i" (mask_4u), "i" (mask_4v)); + + return __pte(val | mask); +} + +static inline pte_t pte_wrprotect(pte_t pte) +{ + const unsigned long mask_4u = _PAGE_WRITE_4U | _PAGE_W_4U; + const unsigned long mask_4v = _PAGE_WRITE_4V | _PAGE_W_4V; + unsigned long val = pte_val(pte), tmp; + + BUILD_BUG_ON((mask_4u & ~(0x0000000000000fffUL)) || + (mask_4v & ~(0xfffffc0000000fffUL))); + + __asm__ __volatile__( + "\n661: andn %0, %3, %0\n" + " nop\n" + "\n662: nop\n" + " nop\n" + " .section .sun4v_2insn_patch, \"ax\"\n" + " .word 661b\n" + " sethi %%uhi(%4), %1\n" + " sllx %1, 32, %1\n" + " .word 662b\n" + " or %1, %%lo(%4), %1\n" + " andn %0, %1, %0\n" + " .previous\n" + : "=r" (val), "=r" (tmp) + : "0" (val), "i" (mask_4u), "i" (mask_4v)); + + return __pte(val); +} + +static inline pte_t pte_mkold(pte_t pte) +{ + const unsigned long mask_4u = _PAGE_ACCESSED_4U; + const unsigned long mask_4v = _PAGE_ACCESSED_4V; + unsigned long mask; + + BUILD_BUG_ON((mask_4u & ~(0x0000000000000fffUL)) || + (mask_4v & ~(0xfffffc0000000000UL))); + + __asm__ __volatile__( + "\n661: mov %1, %0\n" + " nop\n" + " .section .sun4v_2insn_patch, \"ax\"\n" + " .word 661b\n" + " sethi %%uhi(%2), %0\n" + " sllx %0, 32, %0\n" + " .previous\n" + : "=r" (mask) + : "i" (mask_4u), "i" (mask_4v)); + + mask |= _PAGE_R; + + return __pte(pte_val(pte) & ~mask); +} + +static inline pte_t pte_mkyoung(pte_t pte) +{ + const unsigned long mask_4u = _PAGE_ACCESSED_4U; + const unsigned long mask_4v = _PAGE_ACCESSED_4V; + unsigned long mask; + + BUILD_BUG_ON((mask_4u & ~(0x0000000000000fffUL)) || + (mask_4v & ~(0xfffffc0000000000UL))); + + __asm__ __volatile__( + "\n661: mov %1, %0\n" + " nop\n" + " .section .sun4v_2insn_patch, \"ax\"\n" + " .word 661b\n" + " sethi %%uhi(%2), %0\n" + " sllx %0, 32, %0\n" + " .previous\n" + : "=r" (mask) + : "i" (mask_4u), "i" (mask_4v)); + + mask |= _PAGE_R; + + return __pte(pte_val(pte) | mask); +} + +static inline unsigned long pte_young(pte_t pte) +{ + const unsigned long mask_4u = _PAGE_ACCESSED_4U; + const unsigned long mask_4v = _PAGE_ACCESSED_4V; + unsigned long mask; + + BUILD_BUG_ON((mask_4u & ~(0x0000000000000fffUL)) || + (mask_4v & ~(0xfffffc0000000000UL))); + + __asm__ __volatile__( + "\n661: mov %1, %0\n" + " nop\n" + " .section .sun4v_2insn_patch, \"ax\"\n" + " .word 661b\n" + " sethi %%uhi(%2), %0\n" + " sllx %0, 32, %0\n" + " .previous\n" + : "=r" (mask) + : "i" (mask_4u), "i" (mask_4v)); + + return (pte_val(pte) & mask); +} + +static inline unsigned long pte_dirty(pte_t pte) +{ + const unsigned long mask_4u = _PAGE_MODIFIED_4U; + const unsigned long mask_4v = _PAGE_MODIFIED_4V; + unsigned long mask; + + BUILD_BUG_ON((mask_4u & ~(0x0000000000000fffUL)) || + (mask_4v & ~(0xfffffc0000000000UL))); + + __asm__ __volatile__( + "\n661: mov %1, %0\n" + " nop\n" + " .section .sun4v_2insn_patch, \"ax\"\n" + " .word 661b\n" + " sethi %%uhi(%2), %0\n" + " sllx %0, 32, %0\n" + " .previous\n" + : "=r" (mask) + : "i" (mask_4u), "i" (mask_4v)); + + return (pte_val(pte) & mask); +} + +static inline unsigned long pte_write(pte_t pte) +{ + const unsigned long mask_4u = _PAGE_WRITE_4U; + const unsigned long mask_4v = _PAGE_WRITE_4V; + unsigned long mask; + + BUILD_BUG_ON((mask_4u & ~(0x0000000000000fffUL)) || + (mask_4v & ~(0xfffffc0000000000UL))); + + __asm__ __volatile__( + "\n661: mov %1, %0\n" + " nop\n" + " .section .sun4v_2insn_patch, \"ax\"\n" + " .word 661b\n" + " sethi %%uhi(%2), %0\n" + " sllx %0, 32, %0\n" + " .previous\n" + : "=r" (mask) + : "i" (mask_4u), "i" (mask_4v)); + + return (pte_val(pte) & mask); +} + +static inline unsigned long pte_exec(pte_t pte) +{ + const unsigned long mask_4u = _PAGE_EXEC_4U; + const unsigned long mask_4v = _PAGE_EXEC_4V; + unsigned long mask; + + BUILD_BUG_ON((mask_4u & ~(0x00000000fffffc00UL)) || + (mask_4v & ~(0x0000000000000fffUL))); + + __asm__ __volatile__( + "\n661: sethi %%hi(%1), %0\n" + " .section .sun4v_1insn_patch, \"ax\"\n" + " .word 661b\n" + " mov %2, %0\n" + " .previous\n" + : "=r" (mask) + : "i" (mask_4u), "i" (mask_4v)); + + return (pte_val(pte) & mask); +} + +static inline unsigned long pte_read(pte_t pte) +{ + const unsigned long mask_4u = _PAGE_READ_4U; + const unsigned long mask_4v = _PAGE_READ_4V; + unsigned long mask; + + BUILD_BUG_ON((mask_4u & ~(0x0000000000000fffUL)) || + (mask_4v & ~(0xfffffc0000000000UL))); + + __asm__ __volatile__( + "\n661: mov %1, %0\n" + " nop\n" + " .section .sun4v_2insn_patch, \"ax\"\n" + " .word 661b\n" + " sethi %%uhi(%2), %0\n" + " sllx %0, 32, %0\n" + " .previous\n" + : "=r" (mask) + : "i" (mask_4u), "i" (mask_4v)); + + return (pte_val(pte) & mask); +} + +static inline unsigned long pte_file(pte_t pte) +{ + const unsigned long mask_4u = _PAGE_FILE_4U; + const unsigned long mask_4v = _PAGE_FILE_4V; + unsigned long val = pte_val(pte); + + BUILD_BUG_ON((mask_4u & ~(0x0000000000000fffUL)) || + (mask_4v & ~(0x0000000000000fffUL))); + + __asm__ __volatile__( + "\n661: and %0, %2, %0\n" + " .section .sun4v_1insn_patch, \"ax\"\n" + " .word 661b\n" + " and %0, %3, %0\n" + " .previous\n" + : "=r" (val) + : "0" (val), "i" (mask_4u), "i" (mask_4v)); + + return val; +} + +static inline unsigned long pte_present(pte_t pte) +{ + const unsigned long mask_4u = _PAGE_PRESENT_4U; + const unsigned long mask_4v = _PAGE_PRESENT_4V; + unsigned long val = pte_val(pte); + + BUILD_BUG_ON((mask_4u & ~(0x0000000000000fffUL)) || + (mask_4v & ~(0x0000000000000fffUL))); + + __asm__ __volatile__( + "\n661: and %0, %2, %0\n" + " .section .sun4v_1insn_patch, \"ax\"\n" + " .word 661b\n" + " and %0, %3, %0\n" + " .previous\n" + : "=r" (val) + : "0" (val), "i" (mask_4u), "i" (mask_4v)); + + return val; +} #define pmd_set(pmdp, ptep) \ (pmd_val(*(pmdp)) = (__pa((unsigned long) (ptep)) >> 11UL)) -- cgit v1.2.2 From 85dfa19ba92f88fa1c1482f655c7247119dfdcd5 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 13 Feb 2006 00:02:16 -0800 Subject: [SPARC64]: Move devino_to_sysino out of pci_sun4v_asm.S It is not PCI specific, it is for all system interrupts. Signed-off-by: David S. Miller --- include/asm-sparc64/hypervisor.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include') diff --git a/include/asm-sparc64/hypervisor.h b/include/asm-sparc64/hypervisor.h index 5d795ee519..16a40f48be 100644 --- a/include/asm-sparc64/hypervisor.h +++ b/include/asm-sparc64/hypervisor.h @@ -1203,6 +1203,11 @@ struct hv_trap_trace_entry { */ #define HV_FAST_INTR_DEVINO2SYSINO 0xa0 +#ifndef __ASSEMBLY__ +extern unsigned long sun4v_devino_to_sysino(unsigned long devhandle, + unsigned long devino); +#endif + /* intr_getenabled() * TRAP: HV_FAST_TRAP * FUNCTION: HV_FAST_INTR_GETENABLED -- cgit v1.2.2 From 6c0f402f6cc62314ef83b975f3430350dcb6055f Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 13 Feb 2006 00:23:32 -0800 Subject: [SPARC64]: Implement rest of generic interrupt hypervisor calls. Signed-off-by: David S. Miller --- include/asm-sparc64/hypervisor.h | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'include') diff --git a/include/asm-sparc64/hypervisor.h b/include/asm-sparc64/hypervisor.h index 16a40f48be..587a0f6a0a 100644 --- a/include/asm-sparc64/hypervisor.h +++ b/include/asm-sparc64/hypervisor.h @@ -1221,6 +1221,10 @@ extern unsigned long sun4v_devino_to_sysino(unsigned long devhandle, */ #define HV_FAST_INTR_GETENABLED 0xa1 +#ifndef __ASSEMBLY__ +extern unsigned long sun4v_intr_getenabled(unsigned long sysino); +#endif + /* intr_setenabled() * TRAP: HV_FAST_TRAP * FUNCTION: HV_FAST_INTR_SETENABLED @@ -1233,6 +1237,10 @@ extern unsigned long sun4v_devino_to_sysino(unsigned long devhandle, */ #define HV_FAST_INTR_SETENABLED 0xa2 +#ifndef __ASSEMBLY__ +extern void sun4v_intr_setenabled(unsigned long sysino, unsigned long intr_enabled); +#endif + /* intr_getstate() * TRAP: HV_FAST_TRAP * FUNCTION: HV_FAST_INTR_GETSTATE @@ -1245,6 +1253,10 @@ extern unsigned long sun4v_devino_to_sysino(unsigned long devhandle, */ #define HV_FAST_INTR_GETSTATE 0xa3 +#ifndef __ASSEMBLY__ +extern unsigned long sun4v_intr_getstate(unsigned long sysino); +#endif + /* intr_setstate() * TRAP: HV_FAST_TRAP * FUNCTION: HV_FAST_INTR_SETSTATE @@ -1261,6 +1273,10 @@ extern unsigned long sun4v_devino_to_sysino(unsigned long devhandle, */ #define HV_FAST_INTR_SETSTATE 0xa4 +#ifndef __ASSEMBLY__ +extern void sun4v_intr_setstate(unsigned long sysino, unsigned long intr_state); +#endif + /* intr_gettarget() * TRAP: HV_FAST_TRAP * FUNCTION: HV_FAST_INTR_GETTARGET @@ -1275,6 +1291,10 @@ extern unsigned long sun4v_devino_to_sysino(unsigned long devhandle, */ #define HV_FAST_INTR_GETTARGET 0xa5 +#ifndef __ASSEMBLY__ +extern unsigned long sun4v_intr_gettarget(unsigned long sysino); +#endif + /* intr_settarget() * TRAP: HV_FAST_TRAP * FUNCTION: HV_FAST_INTR_SETTARGET @@ -1288,6 +1308,10 @@ extern unsigned long sun4v_devino_to_sysino(unsigned long devhandle, */ #define HV_FAST_INTR_SETTARGET 0xa6 +#ifndef __ASSEMBLY__ +extern void sun4v_intr_settarget(unsigned long sysino, unsigned long cpuid); +#endif + /* PCI IO services. * * See the terminology descriptions in the device interrupt services -- cgit v1.2.2 From e3999574b48125c9bb0c95e3e9f1c696bf96c3e3 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 13 Feb 2006 18:16:10 -0800 Subject: [SPARC64]: Generic sun4v_build_irq(). Signed-off-by: David S. Miller --- include/asm-sparc64/irq.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/asm-sparc64/irq.h b/include/asm-sparc64/irq.h index 8b70edcb80..529a9df1ad 100644 --- a/include/asm-sparc64/irq.h +++ b/include/asm-sparc64/irq.h @@ -111,6 +111,7 @@ extern void disable_irq(unsigned int); #define disable_irq_nosync disable_irq extern void enable_irq(unsigned int); extern unsigned int build_irq(int pil, int inofixup, unsigned long iclr, unsigned long imap); +extern unsigned int sun4v_build_irq(u32 devhandle, unsigned int devino, int pil, unsigned char flags); extern unsigned int sbus_build_irq(void *sbus, unsigned int ino); static __inline__ void set_softint(unsigned long bits) -- cgit v1.2.2 From e77227eb4e17591a6a511b9c0ff6e8ad7350c575 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 13 Feb 2006 20:42:16 -0800 Subject: [SPARC64]: Probe virtual-devices root node on sun4v. This is where we learn how to get the interrupts for things like the hypervisor console device. Signed-off-by: David S. Miller --- include/asm-sparc64/vdev.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 include/asm-sparc64/vdev.h (limited to 'include') diff --git a/include/asm-sparc64/vdev.h b/include/asm-sparc64/vdev.h new file mode 100644 index 0000000000..ebaac41a6e --- /dev/null +++ b/include/asm-sparc64/vdev.h @@ -0,0 +1,18 @@ +/* vdev.h: SUN4V virtual device interfaces and defines. + * + * Copyright (C) 2006 David S. Miller + */ + +#ifndef _SPARC64_VDEV_H +#define _SPARC64_VDEV_H + +#include +#include + +extern u32 sun4v_vdev_devhandle; +extern int sun4v_vdev_root; +extern struct linux_prom_pci_intmap *sun4v_vdev_intmap; +extern int sun4v_vdev_num_intmap; +extern struct linux_prom_pci_intmap sun4v_vdev_intmask; + +#endif /* !(_SPARC64_VDEV_H) */ -- cgit v1.2.2 From 5259d5bfaf5b2953b130e9a500277a905bd37823 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 13 Feb 2006 21:15:44 -0800 Subject: [SPARC64]: Fix comment typo in asm/hypervisor.h Signed-off-by: David S. Miller --- include/asm-sparc64/hypervisor.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/asm-sparc64/hypervisor.h b/include/asm-sparc64/hypervisor.h index 587a0f6a0a..76a9d0fa27 100644 --- a/include/asm-sparc64/hypervisor.h +++ b/include/asm-sparc64/hypervisor.h @@ -912,7 +912,7 @@ struct hv_fault_status { * ARG0: character * RET0: status * ERRORS: EINVAL Illegal character - * EWOULDBLOCK Output buffer currentl full, would block + * EWOULDBLOCK Output buffer currently full, would block * * Send a character to the console device. Only character values * between 0 and 255 may be used. Values outside this range are -- cgit v1.2.2 From c4bea2883974a59ab7a0ac6c01d34f7ae0e8cd8e Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 13 Feb 2006 22:56:27 -0800 Subject: [SPARC64]: Make error codes available from sun4v_intr_get*(). And check for errors at call sites. Signed-off-by: David S. Miller --- include/asm-sparc64/hypervisor.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/asm-sparc64/hypervisor.h b/include/asm-sparc64/hypervisor.h index 76a9d0fa27..f14992ab7f 100644 --- a/include/asm-sparc64/hypervisor.h +++ b/include/asm-sparc64/hypervisor.h @@ -1238,7 +1238,7 @@ extern unsigned long sun4v_intr_getenabled(unsigned long sysino); #define HV_FAST_INTR_SETENABLED 0xa2 #ifndef __ASSEMBLY__ -extern void sun4v_intr_setenabled(unsigned long sysino, unsigned long intr_enabled); +extern unsigned long sun4v_intr_setenabled(unsigned long sysino, unsigned long intr_enabled); #endif /* intr_getstate() @@ -1274,7 +1274,7 @@ extern unsigned long sun4v_intr_getstate(unsigned long sysino); #define HV_FAST_INTR_SETSTATE 0xa4 #ifndef __ASSEMBLY__ -extern void sun4v_intr_setstate(unsigned long sysino, unsigned long intr_state); +extern unsigned long sun4v_intr_setstate(unsigned long sysino, unsigned long intr_state); #endif /* intr_gettarget() @@ -1309,7 +1309,7 @@ extern unsigned long sun4v_intr_gettarget(unsigned long sysino); #define HV_FAST_INTR_SETTARGET 0xa6 #ifndef __ASSEMBLY__ -extern void sun4v_intr_settarget(unsigned long sysino, unsigned long cpuid); +extern unsigned long sun4v_intr_settarget(unsigned long sysino, unsigned long cpuid); #endif /* PCI IO services. -- cgit v1.2.2 From 50f4f23c3bd95afc82e931254a71e7b1b3699fd2 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 14 Feb 2006 01:32:29 -0800 Subject: [SPARC64]: Fix gcc-3.3.x warnings. It doesn't like const variables being passed into "i" constraing asm operations. It's a bug, but there is nothing we can really do but work around it. Based upon a report from Andrew Morton. Signed-off-by: David S. Miller --- include/asm-sparc64/pgtable.h | 143 ++++++++---------------------------------- 1 file changed, 25 insertions(+), 118 deletions(-) (limited to 'include') diff --git a/include/asm-sparc64/pgtable.h b/include/asm-sparc64/pgtable.h index 00eecbb52f..bc446f302e 100644 --- a/include/asm-sparc64/pgtable.h +++ b/include/asm-sparc64/pgtable.h @@ -232,13 +232,8 @@ static inline pte_t pfn_pte(unsigned long pfn, pgprot_t prot) unsigned long paddr = pfn << PAGE_SHIFT; unsigned long sz_bits; - BUILD_BUG_ON(!__builtin_constant_p(_PAGE_SZBITS_4U) || - !__builtin_constant_p(_PAGE_SZBITS_4V)); - sz_bits = 0UL; if (_PAGE_SZBITS_4U != 0UL || _PAGE_SZBITS_4V != 0UL) { - BUILD_BUG_ON((_PAGE_SZBITS_4U & ~(0xfffffc0000000000UL)) || - (_PAGE_SZBITS_4V & ~(0x0000000000000fffUL))); __asm__ __volatile__( "\n661: sethi %uhi(%1), %0\n" " sllx %0, 32, %0\n" @@ -257,10 +252,6 @@ static inline pte_t pfn_pte(unsigned long pfn, pgprot_t prot) /* This one can be done with two shifts. */ static inline unsigned long pte_pfn(pte_t pte) { - const unsigned long pte_paddr_shl_sun4u = 21; - const unsigned long pte_paddr_shr_sun4u = 21 + PAGE_SHIFT; - const unsigned long pte_paddr_shl_sun4v = 8; - const unsigned long pte_paddr_shr_sun4v = 8 + PAGE_SHIFT; unsigned long ret; __asm__ __volatile__( @@ -273,8 +264,8 @@ static inline unsigned long pte_pfn(pte_t pte) " .previous\n" : "=r" (ret) : "r" (pte_val(pte)), - "i" (pte_paddr_shl_sun4u), "i" (pte_paddr_shr_sun4u), - "i" (pte_paddr_shl_sun4v), "i" (pte_paddr_shr_sun4v)); + "i" (21), "i" (21 + PAGE_SHIFT), + "i" (8), "i" (8 + PAGE_SHIFT)); return ret; } @@ -282,22 +273,6 @@ static inline unsigned long pte_pfn(pte_t pte) static inline pte_t pte_modify(pte_t pte, pgprot_t prot) { - const unsigned long preserve_mask_sun4u = (_PAGE_PADDR_4U | - _PAGE_MODIFIED_4U | - _PAGE_ACCESSED_4U | - _PAGE_CP_4U | - _PAGE_CV_4U | - _PAGE_E_4U | - _PAGE_PRESENT_4U | - _PAGE_SZBITS_4U); - const unsigned long preserve_mask_sun4v = (_PAGE_PADDR_4V | - _PAGE_MODIFIED_4V | - _PAGE_ACCESSED_4V | - _PAGE_CP_4V | - _PAGE_CV_4V | - _PAGE_E_4V | - _PAGE_PRESENT_4V | - _PAGE_SZBITS_4V); unsigned long mask, tmp; /* SUN4U: 0x600307ffffffecb8 (negated == 0x9ffcf80000001347) @@ -329,7 +304,12 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t prot) " or %0, %1, %0\n" " .previous\n" : "=r" (mask), "=r" (tmp) - : "i" (preserve_mask_sun4u), "i" (preserve_mask_sun4v)); + : "i" (_PAGE_PADDR_4U | _PAGE_MODIFIED_4U | _PAGE_ACCESSED_4U | + _PAGE_CP_4U | _PAGE_CV_4U | _PAGE_E_4U | _PAGE_PRESENT_4U | + _PAGE_SZBITS_4U), + "i" (_PAGE_PADDR_4V | _PAGE_MODIFIED_4V | _PAGE_ACCESSED_4V | + _PAGE_CP_4V | _PAGE_CV_4V | _PAGE_E_4V | _PAGE_PRESENT_4V | + _PAGE_SZBITS_4V)); return __pte((pte_val(pte) & mask) | (pgprot_val(prot) & ~mask)); } @@ -338,9 +318,6 @@ static inline pte_t pgoff_to_pte(unsigned long off) { off <<= PAGE_SHIFT; - BUILD_BUG_ON((_PAGE_FILE_4U & ~0xfffUL) || - (_PAGE_FILE_4V & ~0xfffUL)); - __asm__ __volatile__( "\n661: or %0, %2, %0\n" " .section .sun4v_1insn_patch, \"ax\"\n" @@ -357,9 +334,6 @@ static inline pgprot_t pgprot_noncached(pgprot_t prot) { unsigned long val = pgprot_val(prot); - BUILD_BUG_ON(((_PAGE_CP_4U | _PAGE_CP_4U | _PAGE_E_4U) & ~(0xfffUL)) || - ((_PAGE_CP_4V | _PAGE_CP_4V | _PAGE_E_4V) & ~(0xfffUL))); - __asm__ __volatile__( "\n661: andn %0, %2, %0\n" " or %0, %3, %0\n" @@ -382,13 +356,8 @@ static inline pgprot_t pgprot_noncached(pgprot_t prot) static inline pte_t pte_mkhuge(pte_t pte) { - const unsigned long mask_4u = _PAGE_SZHUGE_4U; - const unsigned long mask_4v = _PAGE_SZHUGE_4V; unsigned long mask; - BUILD_BUG_ON((mask_4u & ~(0xfffffc0000000000UL)) || - (mask_4v & ~(0xfffUL))); - __asm__ __volatile__( "\n661: sethi %%uhi(%1), %0\n" " sllx %0, 32, %0\n" @@ -398,20 +367,15 @@ static inline pte_t pte_mkhuge(pte_t pte) " nop\n" " .previous\n" : "=r" (mask) - : "i" (mask_4u), "i" (mask_4v)); + : "i" (_PAGE_SZHUGE_4U), "i" (_PAGE_SZHUGE_4V)); return __pte(pte_val(pte) | mask); } static inline pte_t pte_mkdirty(pte_t pte) { - const unsigned long mask_4u = _PAGE_MODIFIED_4U | _PAGE_W_4U; - const unsigned long mask_4v = _PAGE_MODIFIED_4V | _PAGE_W_4V; unsigned long val = pte_val(pte), tmp; - BUILD_BUG_ON((mask_4u & ~(0x0000000000000fffUL)) || - (mask_4v & ~(0xfffffc0000000fffUL))); - __asm__ __volatile__( "\n661: or %0, %3, %0\n" " nop\n" @@ -426,20 +390,16 @@ static inline pte_t pte_mkdirty(pte_t pte) " or %0, %1, %0\n" " .previous\n" : "=r" (val), "=r" (tmp) - : "0" (val), "i" (mask_4u), "i" (mask_4v)); + : "0" (val), "i" (_PAGE_MODIFIED_4U | _PAGE_W_4U), + "i" (_PAGE_MODIFIED_4V | _PAGE_W_4V)); return __pte(val); } static inline pte_t pte_mkclean(pte_t pte) { - const unsigned long mask_4u = _PAGE_MODIFIED_4U | _PAGE_W_4U; - const unsigned long mask_4v = _PAGE_MODIFIED_4V | _PAGE_W_4V; unsigned long val = pte_val(pte), tmp; - BUILD_BUG_ON((mask_4u & ~(0x0000000000000fffUL)) || - (mask_4v & ~(0xfffffc0000000fffUL))); - __asm__ __volatile__( "\n661: andn %0, %3, %0\n" " nop\n" @@ -454,20 +414,16 @@ static inline pte_t pte_mkclean(pte_t pte) " andn %0, %1, %0\n" " .previous\n" : "=r" (val), "=r" (tmp) - : "0" (val), "i" (mask_4u), "i" (mask_4v)); + : "0" (val), "i" (_PAGE_MODIFIED_4U | _PAGE_W_4U), + "i" (_PAGE_MODIFIED_4V | _PAGE_W_4V)); return __pte(val); } static inline pte_t pte_mkwrite(pte_t pte) { - const unsigned long mask_4u = _PAGE_WRITE_4U; - const unsigned long mask_4v = _PAGE_WRITE_4V; unsigned long val = pte_val(pte), mask; - BUILD_BUG_ON((mask_4u & ~(0x0000000000000fffUL)) || - (mask_4v & ~(0xfffffc0000000000UL))); - __asm__ __volatile__( "\n661: mov %1, %0\n" " nop\n" @@ -477,20 +433,15 @@ static inline pte_t pte_mkwrite(pte_t pte) " sllx %0, 32, %0\n" " .previous\n" : "=r" (mask) - : "i" (mask_4u), "i" (mask_4v)); + : "i" (_PAGE_WRITE_4U), "i" (_PAGE_WRITE_4V)); return __pte(val | mask); } static inline pte_t pte_wrprotect(pte_t pte) { - const unsigned long mask_4u = _PAGE_WRITE_4U | _PAGE_W_4U; - const unsigned long mask_4v = _PAGE_WRITE_4V | _PAGE_W_4V; unsigned long val = pte_val(pte), tmp; - BUILD_BUG_ON((mask_4u & ~(0x0000000000000fffUL)) || - (mask_4v & ~(0xfffffc0000000fffUL))); - __asm__ __volatile__( "\n661: andn %0, %3, %0\n" " nop\n" @@ -505,20 +456,16 @@ static inline pte_t pte_wrprotect(pte_t pte) " andn %0, %1, %0\n" " .previous\n" : "=r" (val), "=r" (tmp) - : "0" (val), "i" (mask_4u), "i" (mask_4v)); + : "0" (val), "i" (_PAGE_WRITE_4U | _PAGE_W_4U), + "i" (_PAGE_WRITE_4V | _PAGE_W_4V)); return __pte(val); } static inline pte_t pte_mkold(pte_t pte) { - const unsigned long mask_4u = _PAGE_ACCESSED_4U; - const unsigned long mask_4v = _PAGE_ACCESSED_4V; unsigned long mask; - BUILD_BUG_ON((mask_4u & ~(0x0000000000000fffUL)) || - (mask_4v & ~(0xfffffc0000000000UL))); - __asm__ __volatile__( "\n661: mov %1, %0\n" " nop\n" @@ -528,7 +475,7 @@ static inline pte_t pte_mkold(pte_t pte) " sllx %0, 32, %0\n" " .previous\n" : "=r" (mask) - : "i" (mask_4u), "i" (mask_4v)); + : "i" (_PAGE_ACCESSED_4U), "i" (_PAGE_ACCESSED_4V)); mask |= _PAGE_R; @@ -537,13 +484,8 @@ static inline pte_t pte_mkold(pte_t pte) static inline pte_t pte_mkyoung(pte_t pte) { - const unsigned long mask_4u = _PAGE_ACCESSED_4U; - const unsigned long mask_4v = _PAGE_ACCESSED_4V; unsigned long mask; - BUILD_BUG_ON((mask_4u & ~(0x0000000000000fffUL)) || - (mask_4v & ~(0xfffffc0000000000UL))); - __asm__ __volatile__( "\n661: mov %1, %0\n" " nop\n" @@ -553,7 +495,7 @@ static inline pte_t pte_mkyoung(pte_t pte) " sllx %0, 32, %0\n" " .previous\n" : "=r" (mask) - : "i" (mask_4u), "i" (mask_4v)); + : "i" (_PAGE_ACCESSED_4U), "i" (_PAGE_ACCESSED_4V)); mask |= _PAGE_R; @@ -562,13 +504,8 @@ static inline pte_t pte_mkyoung(pte_t pte) static inline unsigned long pte_young(pte_t pte) { - const unsigned long mask_4u = _PAGE_ACCESSED_4U; - const unsigned long mask_4v = _PAGE_ACCESSED_4V; unsigned long mask; - BUILD_BUG_ON((mask_4u & ~(0x0000000000000fffUL)) || - (mask_4v & ~(0xfffffc0000000000UL))); - __asm__ __volatile__( "\n661: mov %1, %0\n" " nop\n" @@ -578,20 +515,15 @@ static inline unsigned long pte_young(pte_t pte) " sllx %0, 32, %0\n" " .previous\n" : "=r" (mask) - : "i" (mask_4u), "i" (mask_4v)); + : "i" (_PAGE_ACCESSED_4U), "i" (_PAGE_ACCESSED_4V)); return (pte_val(pte) & mask); } static inline unsigned long pte_dirty(pte_t pte) { - const unsigned long mask_4u = _PAGE_MODIFIED_4U; - const unsigned long mask_4v = _PAGE_MODIFIED_4V; unsigned long mask; - BUILD_BUG_ON((mask_4u & ~(0x0000000000000fffUL)) || - (mask_4v & ~(0xfffffc0000000000UL))); - __asm__ __volatile__( "\n661: mov %1, %0\n" " nop\n" @@ -601,20 +533,15 @@ static inline unsigned long pte_dirty(pte_t pte) " sllx %0, 32, %0\n" " .previous\n" : "=r" (mask) - : "i" (mask_4u), "i" (mask_4v)); + : "i" (_PAGE_MODIFIED_4U), "i" (_PAGE_MODIFIED_4V)); return (pte_val(pte) & mask); } static inline unsigned long pte_write(pte_t pte) { - const unsigned long mask_4u = _PAGE_WRITE_4U; - const unsigned long mask_4v = _PAGE_WRITE_4V; unsigned long mask; - BUILD_BUG_ON((mask_4u & ~(0x0000000000000fffUL)) || - (mask_4v & ~(0xfffffc0000000000UL))); - __asm__ __volatile__( "\n661: mov %1, %0\n" " nop\n" @@ -624,20 +551,15 @@ static inline unsigned long pte_write(pte_t pte) " sllx %0, 32, %0\n" " .previous\n" : "=r" (mask) - : "i" (mask_4u), "i" (mask_4v)); + : "i" (_PAGE_WRITE_4U), "i" (_PAGE_WRITE_4V)); return (pte_val(pte) & mask); } static inline unsigned long pte_exec(pte_t pte) { - const unsigned long mask_4u = _PAGE_EXEC_4U; - const unsigned long mask_4v = _PAGE_EXEC_4V; unsigned long mask; - BUILD_BUG_ON((mask_4u & ~(0x00000000fffffc00UL)) || - (mask_4v & ~(0x0000000000000fffUL))); - __asm__ __volatile__( "\n661: sethi %%hi(%1), %0\n" " .section .sun4v_1insn_patch, \"ax\"\n" @@ -645,20 +567,15 @@ static inline unsigned long pte_exec(pte_t pte) " mov %2, %0\n" " .previous\n" : "=r" (mask) - : "i" (mask_4u), "i" (mask_4v)); + : "i" (_PAGE_EXEC_4U), "i" (_PAGE_EXEC_4V)); return (pte_val(pte) & mask); } static inline unsigned long pte_read(pte_t pte) { - const unsigned long mask_4u = _PAGE_READ_4U; - const unsigned long mask_4v = _PAGE_READ_4V; unsigned long mask; - BUILD_BUG_ON((mask_4u & ~(0x0000000000000fffUL)) || - (mask_4v & ~(0xfffffc0000000000UL))); - __asm__ __volatile__( "\n661: mov %1, %0\n" " nop\n" @@ -668,20 +585,15 @@ static inline unsigned long pte_read(pte_t pte) " sllx %0, 32, %0\n" " .previous\n" : "=r" (mask) - : "i" (mask_4u), "i" (mask_4v)); + : "i" (_PAGE_READ_4U), "i" (_PAGE_READ_4V)); return (pte_val(pte) & mask); } static inline unsigned long pte_file(pte_t pte) { - const unsigned long mask_4u = _PAGE_FILE_4U; - const unsigned long mask_4v = _PAGE_FILE_4V; unsigned long val = pte_val(pte); - BUILD_BUG_ON((mask_4u & ~(0x0000000000000fffUL)) || - (mask_4v & ~(0x0000000000000fffUL))); - __asm__ __volatile__( "\n661: and %0, %2, %0\n" " .section .sun4v_1insn_patch, \"ax\"\n" @@ -689,20 +601,15 @@ static inline unsigned long pte_file(pte_t pte) " and %0, %3, %0\n" " .previous\n" : "=r" (val) - : "0" (val), "i" (mask_4u), "i" (mask_4v)); + : "0" (val), "i" (_PAGE_FILE_4U), "i" (_PAGE_FILE_4V)); return val; } static inline unsigned long pte_present(pte_t pte) { - const unsigned long mask_4u = _PAGE_PRESENT_4U; - const unsigned long mask_4v = _PAGE_PRESENT_4V; unsigned long val = pte_val(pte); - BUILD_BUG_ON((mask_4u & ~(0x0000000000000fffUL)) || - (mask_4v & ~(0x0000000000000fffUL))); - __asm__ __volatile__( "\n661: and %0, %2, %0\n" " .section .sun4v_1insn_patch, \"ax\"\n" @@ -710,7 +617,7 @@ static inline unsigned long pte_present(pte_t pte) " and %0, %3, %0\n" " .previous\n" : "=r" (val) - : "0" (val), "i" (mask_4u), "i" (mask_4v)); + : "0" (val), "i" (_PAGE_PRESENT_4U), "i" (_PAGE_PRESENT_4V)); return val; } -- cgit v1.2.2 From 7c3514e4501565d76f9e4dec43e1fc17389f4811 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 15 Feb 2006 00:41:47 -0800 Subject: [SPARC64]: Fixup TSTATE layout diagram in asm/pstate.h Signed-off-by: David S. Miller --- include/asm-sparc64/pstate.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/asm-sparc64/pstate.h b/include/asm-sparc64/pstate.h index 1181d73315..49a7924a89 100644 --- a/include/asm-sparc64/pstate.h +++ b/include/asm-sparc64/pstate.h @@ -28,9 +28,9 @@ /* The V9 TSTATE Register (with SpitFire and Linux extensions). * - * --------------------------------------------------------------- + * --------------------------------------------------------------------- * | Resv | GL | CCR | ASI | %pil | PSTATE | Resv | CWP | - * --------------------------------------------------------------- + * --------------------------------------------------------------------- * 63 43 42 40 39 32 31 24 23 20 19 8 7 5 4 0 */ #define TSTATE_GL _AC(0x0000070000000000,UL) /* Global reg level */ -- cgit v1.2.2 From 7890f794e0e6f7dce2a5f4a03ba64b0b3fe306bd Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 15 Feb 2006 02:26:54 -0800 Subject: [SPARC64]: Add prom_{start,stop}cpu_cpuid(). Use prom_startcpu_cpuid() on SUN4V instead of prom_startcpu(). We should really test for "SUNW,start-cpu-by-cpuid" presence and use it if present even on SUN4U. Signed-off-by: David S. Miller --- include/asm-sparc64/oplib.h | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/asm-sparc64/oplib.h b/include/asm-sparc64/oplib.h index 0631d13475..84618f8a9e 100644 --- a/include/asm-sparc64/oplib.h +++ b/include/asm-sparc64/oplib.h @@ -188,10 +188,18 @@ extern enum prom_output_device prom_query_output_device(void); /* Multiprocessor operations... */ #ifdef CONFIG_SMP -/* Start the CPU with the given device tree node, context table, and context - * at the passed program counter. +/* Start the CPU with the given device tree node at the passed program + * counter with the given arg passed in via register %o0. */ -extern void prom_startcpu(int cpunode, unsigned long pc, unsigned long o0); +extern void prom_startcpu(int cpunode, unsigned long pc, unsigned long arg); + +/* Start the CPU with the given cpu ID at the passed program + * counter with the given arg passed in via register %o0. + */ +extern void prom_startcpu_cpuid(int cpuid, unsigned long pc, unsigned long arg); + +/* Stop the CPU with the given cpu ID. */ +extern void prom_stopcpu_cpuid(int cpuid); /* Stop the current CPU. */ extern void prom_stopself(void); -- cgit v1.2.2 From 9d29a3fafd06534ad73427fee3c968c094d05b9b Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 15 Feb 2006 19:48:54 -0800 Subject: [SPARC64]: Decode virtual-devices interrupts correctly. Need to translate through the interrupt-map{,-mask] properties. Signed-off-by: David S. Miller --- include/asm-sparc64/vdev.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/asm-sparc64/vdev.h b/include/asm-sparc64/vdev.h index ebaac41a6e..996e6be7b9 100644 --- a/include/asm-sparc64/vdev.h +++ b/include/asm-sparc64/vdev.h @@ -7,12 +7,10 @@ #define _SPARC64_VDEV_H #include -#include extern u32 sun4v_vdev_devhandle; extern int sun4v_vdev_root; -extern struct linux_prom_pci_intmap *sun4v_vdev_intmap; -extern int sun4v_vdev_num_intmap; -extern struct linux_prom_pci_intmap sun4v_vdev_intmask; + +extern unsigned int sun4v_vdev_device_interrupt(unsigned int); #endif /* !(_SPARC64_VDEV_H) */ -- cgit v1.2.2 From bc45e32e0fbf661d0c5c5b9c981bc0fe5da4901f Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 5 Mar 2006 16:46:58 -0800 Subject: [SPARC]: Kill off these __put_user_ret things. They are bogus and haven't been referenced in years. Signed-off-by: David S. Miller --- include/asm-sparc/uaccess.h | 47 ------------------------------------------- include/asm-sparc64/uaccess.h | 37 ---------------------------------- 2 files changed, 84 deletions(-) (limited to 'include') diff --git a/include/asm-sparc/uaccess.h b/include/asm-sparc/uaccess.h index f8f1ec1f06..3cf132e1aa 100644 --- a/include/asm-sparc/uaccess.h +++ b/include/asm-sparc/uaccess.h @@ -120,17 +120,6 @@ case 8: __put_user_asm(x,d,addr,__pu_ret); break; \ default: __pu_ret = __put_user_bad(); break; \ } } else { __pu_ret = -EFAULT; } __pu_ret; }) -#define __put_user_check_ret(x,addr,size,retval) ({ \ -register int __foo __asm__ ("l1"); \ -if (__access_ok(addr,size)) { \ -switch (size) { \ -case 1: __put_user_asm_ret(x,b,addr,retval,__foo); break; \ -case 2: __put_user_asm_ret(x,h,addr,retval,__foo); break; \ -case 4: __put_user_asm_ret(x,,addr,retval,__foo); break; \ -case 8: __put_user_asm_ret(x,d,addr,retval,__foo); break; \ -default: if (__put_user_bad()) return retval; break; \ -} } else return retval; }) - #define __put_user_nocheck(x,addr,size) ({ \ register int __pu_ret; \ switch (size) { \ @@ -141,16 +130,6 @@ case 8: __put_user_asm(x,d,addr,__pu_ret); break; \ default: __pu_ret = __put_user_bad(); break; \ } __pu_ret; }) -#define __put_user_nocheck_ret(x,addr,size,retval) ({ \ -register int __foo __asm__ ("l1"); \ -switch (size) { \ -case 1: __put_user_asm_ret(x,b,addr,retval,__foo); break; \ -case 2: __put_user_asm_ret(x,h,addr,retval,__foo); break; \ -case 4: __put_user_asm_ret(x,,addr,retval,__foo); break; \ -case 8: __put_user_asm_ret(x,d,addr,retval,__foo); break; \ -default: if (__put_user_bad()) return retval; break; \ -} }) - #define __put_user_asm(x,size,addr,ret) \ __asm__ __volatile__( \ "/* Put user asm, inline. */\n" \ @@ -170,32 +149,6 @@ __asm__ __volatile__( \ : "=&r" (ret) : "r" (x), "m" (*__m(addr)), \ "i" (-EFAULT)) -#define __put_user_asm_ret(x,size,addr,ret,foo) \ -if (__builtin_constant_p(ret) && ret == -EFAULT) \ -__asm__ __volatile__( \ - "/* Put user asm ret, inline. */\n" \ -"1:\t" "st"#size " %1, %2\n\n\t" \ - ".section __ex_table,#alloc\n\t" \ - ".align 4\n\t" \ - ".word 1b, __ret_efault\n\n\t" \ - ".previous\n\n\t" \ - : "=r" (foo) : "r" (x), "m" (*__m(addr))); \ -else \ -__asm__ __volatile( \ - "/* Put user asm ret, inline. */\n" \ -"1:\t" "st"#size " %1, %2\n\n\t" \ - ".section .fixup,#alloc,#execinstr\n\t" \ - ".align 4\n" \ -"3:\n\t" \ - "ret\n\t" \ - " restore %%g0, %3, %%o0\n\t" \ - ".previous\n\n\t" \ - ".section __ex_table,#alloc\n\t" \ - ".align 4\n\t" \ - ".word 1b, 3b\n\n\t" \ - ".previous\n\n\t" \ - : "=r" (foo) : "r" (x), "m" (*__m(addr)), "i" (ret)) - extern int __put_user_bad(void); #define __get_user_check(x,addr,size,type) ({ \ diff --git a/include/asm-sparc64/uaccess.h b/include/asm-sparc64/uaccess.h index c91d1e38ea..0c375a989b 100644 --- a/include/asm-sparc64/uaccess.h +++ b/include/asm-sparc64/uaccess.h @@ -114,16 +114,6 @@ case 8: __put_user_asm(data,x,addr,__pu_ret); break; \ default: __pu_ret = __put_user_bad(); break; \ } __pu_ret; }) -#define __put_user_nocheck_ret(data,addr,size,retval) ({ \ -register int __foo __asm__ ("l1"); \ -switch (size) { \ -case 1: __put_user_asm_ret(data,b,addr,retval,__foo); break; \ -case 2: __put_user_asm_ret(data,h,addr,retval,__foo); break; \ -case 4: __put_user_asm_ret(data,w,addr,retval,__foo); break; \ -case 8: __put_user_asm_ret(data,x,addr,retval,__foo); break; \ -default: if (__put_user_bad()) return retval; break; \ -} }) - #define __put_user_asm(x,size,addr,ret) \ __asm__ __volatile__( \ "/* Put user asm, inline. */\n" \ @@ -143,33 +133,6 @@ __asm__ __volatile__( \ : "=r" (ret) : "r" (x), "r" (__m(addr)), \ "i" (-EFAULT)) -#define __put_user_asm_ret(x,size,addr,ret,foo) \ -if (__builtin_constant_p(ret) && ret == -EFAULT) \ -__asm__ __volatile__( \ - "/* Put user asm ret, inline. */\n" \ -"1:\t" "st"#size "a %1, [%2] %%asi\n\n\t" \ - ".section __ex_table,\"a\"\n\t" \ - ".align 4\n\t" \ - ".word 1b, __ret_efault\n\n\t" \ - ".previous\n\n\t" \ - : "=r" (foo) : "r" (x), "r" (__m(addr))); \ -else \ -__asm__ __volatile__( \ - "/* Put user asm ret, inline. */\n" \ -"1:\t" "st"#size "a %1, [%2] %%asi\n\n\t" \ - ".section .fixup,#alloc,#execinstr\n\t" \ - ".align 4\n" \ -"3:\n\t" \ - "ret\n\t" \ - " restore %%g0, %3, %%o0\n\n\t" \ - ".previous\n\t" \ - ".section __ex_table,\"a\"\n\t" \ - ".align 4\n\t" \ - ".word 1b, 3b\n\n\t" \ - ".previous\n\n\t" \ - : "=r" (foo) : "r" (x), "r" (__m(addr)), \ - "i" (ret)) - extern int __put_user_bad(void); #define __get_user_nocheck(data,addr,size,type) ({ \ -- cgit v1.2.2 From 94f8762db9a80ed34252e9fe5fa38be87bb7826b Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 16 Feb 2006 14:26:53 -0800 Subject: [SPARC64]: Add sun4v_cpu_qconf() hypervisor call. Call it from register_one_mondo(). Signed-off-by: David S. Miller --- include/asm-sparc64/hypervisor.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'include') diff --git a/include/asm-sparc64/hypervisor.h b/include/asm-sparc64/hypervisor.h index f14992ab7f..cd5fbcd955 100644 --- a/include/asm-sparc64/hypervisor.h +++ b/include/asm-sparc64/hypervisor.h @@ -301,6 +301,12 @@ #define HV_CPU_QUEUE_RES_ERROR 0x3e #define HV_CPU_QUEUE_NONRES_ERROR 0x3f +#ifndef __ASSEMBLY__ +extern unsigned long sun4v_cpu_qconf(unsigned long type, + unsigned long queue_paddr, + unsigned long num_queue_entries); +#endif + /* cpu_qinfo() * TRAP: HV_FAST_TRAP * FUNCTION: HV_FAST_CPU_QINFO -- cgit v1.2.2 From 4ff7ac417d4b628c23df3ae8301d17e29e6e8f16 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 16 Feb 2006 16:22:26 -0800 Subject: [SPARC64]: Add GET_GL_GLOBAL() macro for SUN4V. So we can read the %gl register for debugging. Signed-off-by: David S. Miller --- include/asm-sparc64/head.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include') diff --git a/include/asm-sparc64/head.h b/include/asm-sparc64/head.h index c4ac3e87aa..67960a751f 100644 --- a/include/asm-sparc64/head.h +++ b/include/asm-sparc64/head.h @@ -8,6 +8,10 @@ #define SET_GL(val) \ .word 0xa1902000 | val + /* rdpr %gl, %gN */ +#define GET_GL_GLOBAL(N) \ + .word 0x81540000 | (N << 25) + #define KERNBASE 0x400000 #define PTREGS_OFF (STACK_BIAS + STACKFRAME_SZ) -- cgit v1.2.2 From 72aff53f1fe74153eccef303ab2f79de888d248c Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 17 Feb 2006 01:29:17 -0800 Subject: [SPARC64]: Get SUN4V SMP working. The sibling cpu bringup is extremely fragile. We can only perform the most basic calls until we take over the trap table from the firmware/hypervisor on the new cpu. This means no accesses to %g4, %g5, %g6 since those can't be TLB translated without our trap handlers. In order to achieve this: 1) Change sun4v_init_mondo_queues() so that it can operate in several modes. It can allocate the queues, or install them in the current processor, or both. The boot cpu does both in it's call early on. Later, the boot cpu allocates the sibling cpu queue, starts the sibling cpu, then the sibling cpu loads them in. 2) init_cur_cpu_trap() is changed to take the current_thread_info() as an argument instead of reading %g6 directly on the current cpu. 3) Create a trampoline stack for the sibling cpus. We do our basic kernel calls using this stack, which is locked into the kernel image, then go to our proper thread stack after taking over the trap table. 4) While we are in this delicate startup state, we put 0xdeadbeef into %g4/%g5/%g6 in order to catch accidental accesses. 5) On the final prom_set_trap_table*() call, we put &init_thread_union into %g6. This is a hack to make prom_world(0) work. All that wants to do is restore the %asi register using get_thread_current_ds(). Longer term we should just do the OBP calls to set the trap table by hand just like we do for everything else. This would avoid that silly prom_world(0) issue, then we can remove the init_thread_union hack. Signed-off-by: David S. Miller --- include/asm-sparc64/cpudata.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/asm-sparc64/cpudata.h b/include/asm-sparc64/cpudata.h index 5a970f5ed9..771aa94dfd 100644 --- a/include/asm-sparc64/cpudata.h +++ b/include/asm-sparc64/cpudata.h @@ -77,7 +77,7 @@ struct trap_per_cpu { unsigned long __pad2[4]; } __attribute__((aligned(64))); extern struct trap_per_cpu trap_block[NR_CPUS]; -extern void init_cur_cpu_trap(void); +extern void init_cur_cpu_trap(struct thread_info *); extern void setup_tba(void); #ifdef CONFIG_SMP -- cgit v1.2.2 From ebd8c56c5ae154e2c6cfb7453a76a4e7265b2377 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 17 Feb 2006 08:38:06 -0800 Subject: [SPARC64]: Fix uniprocessor IRQ targetting on SUN4V. We need to use the real hardware processor ID when targetting interrupts, not the "define to 0" thing the uniprocessor build gives us. Also, fill in the Node-ID and Agent-ID fields properly on sun4u/Safari. Signed-off-by: David S. Miller --- include/asm-sparc64/cpudata.h | 6 ++---- include/asm-sparc64/irq.h | 3 +++ 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/asm-sparc64/cpudata.h b/include/asm-sparc64/cpudata.h index 771aa94dfd..84656f1895 100644 --- a/include/asm-sparc64/cpudata.h +++ b/include/asm-sparc64/cpudata.h @@ -80,7 +80,6 @@ extern struct trap_per_cpu trap_block[NR_CPUS]; extern void init_cur_cpu_trap(struct thread_info *); extern void setup_tba(void); -#ifdef CONFIG_SMP struct cpuid_patch_entry { unsigned int addr; unsigned int cheetah_safari[4]; @@ -89,7 +88,6 @@ struct cpuid_patch_entry { unsigned int sun4v[4]; }; extern struct cpuid_patch_entry __cpuid_patch, __cpuid_patch_end; -#endif struct sun4v_1insn_patch_entry { unsigned int addr; @@ -123,8 +121,6 @@ extern struct sun4v_2insn_patch_entry __sun4v_2insn_patch, #include -#ifdef CONFIG_SMP - #define __GET_CPUID(REG) \ /* Spitfire implementation (default). */ \ 661: ldxa [%g0] ASI_UPA_CONFIG, REG; \ @@ -156,6 +152,8 @@ extern struct sun4v_2insn_patch_entry __sun4v_2insn_patch, nop; \ .previous; +#ifdef CONFIG_SMP + #define TRAP_LOAD_TRAP_BLOCK(DEST, TMP) \ __GET_CPUID(TMP) \ sethi %hi(trap_block), DEST; \ diff --git a/include/asm-sparc64/irq.h b/include/asm-sparc64/irq.h index 529a9df1ad..de33d6e1af 100644 --- a/include/asm-sparc64/irq.h +++ b/include/asm-sparc64/irq.h @@ -72,8 +72,11 @@ struct ino_bucket { #define IMAP_VALID 0x80000000 /* IRQ Enabled */ #define IMAP_TID_UPA 0x7c000000 /* UPA TargetID */ #define IMAP_TID_JBUS 0x7c000000 /* JBUS TargetID */ +#define IMAP_TID_SHIFT 26 #define IMAP_AID_SAFARI 0x7c000000 /* Safari AgentID */ +#define IMAP_AID_SHIFT 26 #define IMAP_NID_SAFARI 0x03e00000 /* Safari NodeID */ +#define IMAP_NID_SHIFT 21 #define IMAP_IGN 0x000007c0 /* IRQ Group Number */ #define IMAP_INO 0x0000003f /* IRQ Number */ #define IMAP_INR 0x000007ff /* Full interrupt number*/ -- cgit v1.2.2 From 97532f598273d03cab8bb5206669b6fdd654eb63 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 17 Feb 2006 10:14:38 -0800 Subject: [SPARC64]: Add HWCAP_SPARC_BLKINIT elf capability flag for Niagara. Signed-off-by: David S. Miller --- include/asm-sparc64/elf.h | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) (limited to 'include') diff --git a/include/asm-sparc64/elf.h b/include/asm-sparc64/elf.h index 69539a8ab8..303d85e2f8 100644 --- a/include/asm-sparc64/elf.h +++ b/include/asm-sparc64/elf.h @@ -10,6 +10,7 @@ #ifdef __KERNEL__ #include #include +#include #endif /* @@ -68,6 +69,7 @@ #define HWCAP_SPARC_MULDIV 8 #define HWCAP_SPARC_V9 16 #define HWCAP_SPARC_ULTRA3 32 +#define HWCAP_SPARC_BLKINIT 64 /* * These are used to set parameters in the core dumps. @@ -145,11 +147,21 @@ typedef struct { instruction set this cpu supports. */ /* On Ultra, we support all of the v8 capabilities. */ -#define ELF_HWCAP ((HWCAP_SPARC_FLUSH | HWCAP_SPARC_STBAR | \ - HWCAP_SPARC_SWAP | HWCAP_SPARC_MULDIV | \ - HWCAP_SPARC_V9) | \ - ((tlb_type == cheetah || tlb_type == cheetah_plus) ? \ - HWCAP_SPARC_ULTRA3 : 0)) +static inline unsigned int sparc64_elf_hwcap(void) +{ + unsigned int cap = (HWCAP_SPARC_FLUSH | HWCAP_SPARC_STBAR | + HWCAP_SPARC_SWAP | HWCAP_SPARC_MULDIV | + HWCAP_SPARC_V9); + + if (tlb_type == cheetah || tlb_type == cheetah_plus) + cap |= HWCAP_SPARC_ULTRA3; + else if (tlb_type == hypervisor) + cap |= HWCAP_SPARC_BLKINIT; + + return cap; +} + +#define ELF_HWCAP sparc64_elf_hwcap(); /* This yields a string that ld.so will use to load implementation specific libraries for optimization. This is more specific in -- cgit v1.2.2 From c857e3fdbc306e95fdcaad1d8f3ea6bc8e7eea99 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 17 Feb 2006 10:35:23 -0800 Subject: [SPARC64]: __bzero_noasi --> __clear_user Signed-off-by: David S. Miller --- include/asm-sparc64/uaccess.h | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'include') diff --git a/include/asm-sparc64/uaccess.h b/include/asm-sparc64/uaccess.h index 0c375a989b..afe236ba55 100644 --- a/include/asm-sparc64/uaccess.h +++ b/include/asm-sparc64/uaccess.h @@ -252,14 +252,7 @@ copy_in_user(void __user *to, void __user *from, unsigned long size) } #define __copy_in_user copy_in_user -extern unsigned long __must_check __bzero_noasi(void __user *, unsigned long); - -static inline unsigned long __must_check -__clear_user(void __user *addr, unsigned long size) -{ - - return __bzero_noasi(addr, size); -} +extern unsigned long __must_check __clear_user(void __user *, unsigned long); #define clear_user __clear_user -- cgit v1.2.2 From 3763be32d591cacf808c36390a8af3f2784cde5f Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 17 Feb 2006 12:33:13 -0800 Subject: [SPARC64]: Define ARCH_HAS_READ_CURRENT_TIMER. This gives more consistent bogomips and delay() semantics, especially on sun4v. It gives weird looking values though... Signed-off-by: David S. Miller --- include/asm-sparc64/timex.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'include') diff --git a/include/asm-sparc64/timex.h b/include/asm-sparc64/timex.h index 9e8d4175bc..2a5e4ebaad 100644 --- a/include/asm-sparc64/timex.h +++ b/include/asm-sparc64/timex.h @@ -14,4 +14,10 @@ typedef unsigned long cycles_t; #define get_cycles() tick_ops->get_tick() +#define ARCH_HAS_READ_CURRENT_TIMER 1 +#define read_current_timer(timer_val_p) \ +({ *timer_val_p = tick_ops->get_tick(); \ + 0; \ +}) + #endif -- cgit v1.2.2 From 8b234274418d6d79527c4ac3a72da446ca4cb35f Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 17 Feb 2006 18:01:02 -0800 Subject: [SPARC64]: More TLB/TSB handling fixes. The SUN4V convention with non-shared TSBs is that the context bit of the TAG is clear. So we have to choose an "invalid" bit and initialize new TSBs appropriately. Otherwise a zero TAG looks "valid". Make sure, for the window fixup cases, that we use the right global registers and that we don't potentially trample on the live global registers in etrap/rtrap handling (%g2 and %g6) and that we put the missing virtual address properly in %g5. Signed-off-by: David S. Miller --- include/asm-sparc64/tsb.h | 8 ++++++++ include/asm-sparc64/ttable.h | 12 ++++++------ 2 files changed, 14 insertions(+), 6 deletions(-) (limited to 'include') diff --git a/include/asm-sparc64/tsb.h b/include/asm-sparc64/tsb.h index 7f3abc32c4..6e6768067e 100644 --- a/include/asm-sparc64/tsb.h +++ b/include/asm-sparc64/tsb.h @@ -12,6 +12,8 @@ * * ldxa [%g0] ASI_{D,I}MMU_TSB_8KB_PTR, %g1 * ldxa [%g0] ASI_{D,I}MMU, %g6 + * sllx %g6, 22, %g6 + * srlx %g6, 22, %g6 * ldda [%g1] ASI_NUCLEUS_QUAD_LDD, %g4 * cmp %g4, %g6 * bne,pn %xcc, tsb_miss_{d,i}tlb @@ -29,6 +31,9 @@ * ------------------------------------------------- * 63 61 60 48 47 42 41 0 * + * But actually, since we use per-mm TSB's, we zero out the CONTEXT + * field. + * * Like the powerpc hashtables we need to use locking in order to * synchronize while we update the entries. PTE updates need locking * as well. @@ -42,6 +47,9 @@ #define TSB_TAG_LOCK_BIT 47 #define TSB_TAG_LOCK_HIGH (1 << (TSB_TAG_LOCK_BIT - 32)) +#define TSB_TAG_INVALID_BIT 46 +#define TSB_TAG_INVALID_HIGH (1 << (TSB_TAG_INVALID_BIT - 32)) + #define TSB_MEMBAR membar #StoreStore /* Some cpus support physical address quad loads. We want to use diff --git a/include/asm-sparc64/ttable.h b/include/asm-sparc64/ttable.h index 9e28b240f3..2d5e3c464d 100644 --- a/include/asm-sparc64/ttable.h +++ b/include/asm-sparc64/ttable.h @@ -184,20 +184,20 @@ ldxa [%g0] ASI_SCRATCHPAD, %g2; \ ldx [%g2 + HV_FAULT_I_ADDR_OFFSET], %g4; \ ldx [%g2 + HV_FAULT_I_CTX_OFFSET], %g5; \ - srlx %g4, 22, %g7; \ - sllx %g5, 48, %g6; \ + srlx %g4, 22, %g6; \ ba,pt %xcc, sun4v_itsb_miss; \ - or %g6, %g7, %g6; \ + nop; \ + nop; \ nop; #define SUN4V_DTSB_MISS \ ldxa [%g0] ASI_SCRATCHPAD, %g2; \ ldx [%g2 + HV_FAULT_D_ADDR_OFFSET], %g4; \ ldx [%g2 + HV_FAULT_D_CTX_OFFSET], %g5; \ - srlx %g4, 22, %g7; \ - sllx %g5, 48, %g6; \ + srlx %g4, 22, %g6; \ ba,pt %xcc, sun4v_dtsb_miss; \ - or %g6, %g7, %g6; \ + nop; \ + nop; \ nop; /* Before touching these macros, you owe it to yourself to go and -- cgit v1.2.2 From f6c1fe529217788f095f6953c2b66bec1196ad3d Mon Sep 17 00:00:00 2001 From: "Fabio M. Di Nitto" Date: Sat, 18 Feb 2006 00:32:31 -0800 Subject: [SPARC64] Fix build if CONFIG_HUGETLB_PAGE is not set Signed-off-by: Fabio M. Di Nitto Signed-off-by: David S. Miller --- include/asm-sparc64/pgtable.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/asm-sparc64/pgtable.h b/include/asm-sparc64/pgtable.h index bc446f302e..bab7defd8b 100644 --- a/include/asm-sparc64/pgtable.h +++ b/include/asm-sparc64/pgtable.h @@ -354,6 +354,7 @@ static inline pgprot_t pgprot_noncached(pgprot_t prot) */ #define pgprot_noncached pgprot_noncached +#ifdef CONFIG_HUGETLB_PAGE static inline pte_t pte_mkhuge(pte_t pte) { unsigned long mask; @@ -371,6 +372,7 @@ static inline pte_t pte_mkhuge(pte_t pte) return __pte(pte_val(pte) | mask); } +#endif static inline pte_t pte_mkdirty(pte_t pte) { -- cgit v1.2.2 From 0f15952ac8641bde1045162ffd4a7b474cc318b0 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sat, 18 Feb 2006 12:43:16 -0800 Subject: [SPARC64]: Export a PAGE_SHARED symbol. For drivers/media/*, noticed by Fabbione. Signed-off-by: David S. Miller --- include/asm-sparc64/pgtable.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/asm-sparc64/pgtable.h b/include/asm-sparc64/pgtable.h index bab7defd8b..6c8126b2de 100644 --- a/include/asm-sparc64/pgtable.h +++ b/include/asm-sparc64/pgtable.h @@ -206,6 +206,7 @@ extern unsigned long pte_sz_bits(unsigned long size); extern pgprot_t PAGE_KERNEL; extern pgprot_t PAGE_KERNEL_LOCKED; extern pgprot_t PAGE_COPY; +extern pgprot_t PAGE_SHARED; /* XXX This uglyness is for the atyfb driver's sparc mmap() support. XXX */ extern unsigned long _PAGE_IE; -- cgit v1.2.2 From 1bd0cd74d102a527b2a72907698d73fad4b82cbd Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 21 Feb 2006 15:41:01 -0800 Subject: [SPARC64]: Kill cpudata->idle_volume. Set, but never used. We used to use this for dynamic IRQ retargetting, but that code died a long time ago. Signed-off-by: David S. Miller --- include/asm-sparc64/cpudata.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/asm-sparc64/cpudata.h b/include/asm-sparc64/cpudata.h index 84656f1895..c66a81bbc8 100644 --- a/include/asm-sparc64/cpudata.h +++ b/include/asm-sparc64/cpudata.h @@ -19,7 +19,7 @@ typedef struct { unsigned int __softirq_pending; /* must be 1st, see rtrap.S */ unsigned int multiplier; unsigned int counter; - unsigned int idle_volume; + unsigned int __pad1; unsigned long clock_tick; /* %tick's per second */ unsigned long udelay_val; -- cgit v1.2.2 From 6f5374c91f0dd1d92408ed44c066c32bcce5ce69 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 21 Feb 2006 15:42:09 -0800 Subject: [SPARC64]: Add sun4v_cpu_yield(). Signed-off-by: David S. Miller --- include/asm-sparc64/hypervisor.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include') diff --git a/include/asm-sparc64/hypervisor.h b/include/asm-sparc64/hypervisor.h index cd5fbcd955..726e2ea03c 100644 --- a/include/asm-sparc64/hypervisor.h +++ b/include/asm-sparc64/hypervisor.h @@ -258,6 +258,9 @@ */ #define HV_FAST_CPU_YIELD 0x12 +#ifndef __ASSEMBLY__ +extern unsigned long sun4v_cpu_yield(void); +#endif /* cpu_qconf() * TRAP: HV_FAST_TRAP -- cgit v1.2.2 From d7744a09504d5ae84edc8289a02254e1f2102410 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 21 Feb 2006 22:31:11 -0800 Subject: [SPARC64]: Create a seperate kernel TSB for 4MB/256MB mappings. It can map all of the linear kernel mappings with zero TSB hash conflicts for systems with 16GB or less ram. In such cases, on SUN4V, once we load up this TSB the first time with all the mappings, we never take a linear kernel mapping TLB miss ever again, the hypervisor handles them all. Signed-off-by: David S. Miller --- include/asm-sparc64/tsb.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'include') diff --git a/include/asm-sparc64/tsb.h b/include/asm-sparc64/tsb.h index 6e6768067e..e82612cd9f 100644 --- a/include/asm-sparc64/tsb.h +++ b/include/asm-sparc64/tsb.h @@ -243,6 +243,7 @@ extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end; #define KERNEL_TSB_SIZE_BYTES (32 * 1024) #define KERNEL_TSB_NENTRIES \ (KERNEL_TSB_SIZE_BYTES / 16) +#define KERNEL_TSB4M_NENTRIES 4096 /* Do a kernel TSB lookup at tl>0 on VADDR+TAG, branch to OK_LABEL * on TSB hit. REG1, REG2, REG3, and REG4 are used as temporaries @@ -263,4 +264,18 @@ extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end; be,a,pt %xcc, OK_LABEL; \ mov REG4, REG1; + /* This version uses a trick, the TAG is already (VADDR >> 22) so + * we can make use of that for the index computation. + */ +#define KERN_TSB4M_LOOKUP_TL1(TAG, REG1, REG2, REG3, REG4, OK_LABEL) \ + sethi %hi(swapper_4m_tsb), REG1; \ + or REG1, %lo(swapper_4m_tsb), REG1; \ + and TAG, (KERNEL_TSB_NENTRIES - 1), REG2; \ + sllx REG2, 4, REG2; \ + add REG1, REG2, REG2; \ + KTSB_LOAD_QUAD(REG2, REG3); \ + cmp REG3, TAG; \ + be,a,pt %xcc, OK_LABEL; \ + mov REG4, REG1; + #endif /* !(_SPARC64_TSB_H) */ -- cgit v1.2.2 From 0f05da6d577b80eb00f15994c86e4812ae60f1b9 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 22 Feb 2006 16:20:11 -0800 Subject: [SPARC64]: Fix %tstate ASI handling in start_thread{,32}() Niagara helps us find a ancient bug in the sparc64 port :-) The ASI_* values are plain constant defines, thus signed 32-bit on sparc64. To put shift this into the regs->tstate value we were doing or'ing "(ASI_PNF << 24)" into there. ASI_PNF is 0x82 and shifted left by 24 makes that topmost bit the sign bit in a 32-bit value. This would get sign extended to 64-bits and thus corrupt the top-half of the reg->tstate value. This never caused problems in pre-Niagara cpus because the only thing up there were the condition code values. But Niagara has the global register level field, and this all 1's value is illegal there so Niagara gives an illegal instruction trap due to this bug. I'm pretty sure this bug is about as old as the sparc64 port itself. This also points out that we weren't setting ASI_PNF for 32-bit tasks. We should, so fix that while we're here. Signed-off-by: David S. Miller --- include/asm-sparc64/processor.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/asm-sparc64/processor.h b/include/asm-sparc64/processor.h index b3889f3f94..685479fb43 100644 --- a/include/asm-sparc64/processor.h +++ b/include/asm-sparc64/processor.h @@ -91,7 +91,8 @@ extern unsigned long thread_saved_pc(struct task_struct *); /* Do necessary setup to start up a newly executed thread. */ #define start_thread(regs, pc, sp) \ do { \ - regs->tstate = (regs->tstate & (TSTATE_CWP)) | (TSTATE_INITIAL_MM|TSTATE_IE) | (ASI_PNF << 24); \ + unsigned long __asi = ASI_PNF; \ + regs->tstate = (regs->tstate & (TSTATE_CWP)) | (TSTATE_INITIAL_MM|TSTATE_IE) | (__asi << 24UL); \ regs->tpc = ((pc & (~3)) - 4); \ regs->tnpc = regs->tpc + 4; \ regs->y = 0; \ @@ -128,10 +129,10 @@ do { \ #define start_thread32(regs, pc, sp) \ do { \ + unsigned long __asi = ASI_PNF; \ pc &= 0x00000000ffffffffUL; \ sp &= 0x00000000ffffffffUL; \ -\ - regs->tstate = (regs->tstate & (TSTATE_CWP))|(TSTATE_INITIAL_MM|TSTATE_IE|TSTATE_AM); \ + regs->tstate = (regs->tstate & (TSTATE_CWP))|(TSTATE_INITIAL_MM|TSTATE_IE|TSTATE_AM) | (__asi << 24UL); \ regs->tpc = ((pc & (~3)) - 4); \ regs->tnpc = regs->tpc + 4; \ regs->y = 0; \ -- cgit v1.2.2 From a0663a79ad4faebe1db4a56e2e767b120b12333a Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 23 Feb 2006 14:19:28 -0800 Subject: [SPARC64]: Fix TLB context allocation with SMT style shared TLBs. The context allocation scheme we use depends upon there being a 1<-->1 mapping from cpu to physical TLB for correctness. Chips like Niagara break this assumption. So what we do is notify all cpus with a cross call when the context version number changes, and if necessary this makes them allocate a valid context for the address space they are running at the time. Stress tested with make -j1024, make -j2048, and make -j4096 kernel builds on a 32-strand, 8 core, T2000 with 16GB of ram. Signed-off-by: David S. Miller --- include/asm-sparc64/mmu.h | 1 + include/asm-sparc64/mmu_context.h | 25 ++++++++++++------------- 2 files changed, 13 insertions(+), 13 deletions(-) (limited to 'include') diff --git a/include/asm-sparc64/mmu.h b/include/asm-sparc64/mmu.h index 473d990848..1504d303a1 100644 --- a/include/asm-sparc64/mmu.h +++ b/include/asm-sparc64/mmu.h @@ -102,6 +102,7 @@ extern void __tsb_insert(unsigned long ent, unsigned long tag, unsigned long pte extern void tsb_flush(unsigned long ent, unsigned long tag); typedef struct { + spinlock_t lock; unsigned long sparc64_ctx_val; struct tsb *tsb; unsigned long tsb_rss_limit; diff --git a/include/asm-sparc64/mmu_context.h b/include/asm-sparc64/mmu_context.h index eb660b1609..4be40c58e3 100644 --- a/include/asm-sparc64/mmu_context.h +++ b/include/asm-sparc64/mmu_context.h @@ -19,6 +19,12 @@ extern unsigned long tlb_context_cache; extern unsigned long mmu_context_bmap[]; extern void get_new_mmu_context(struct mm_struct *mm); +#ifdef CONFIG_SMP +extern void smp_new_mmu_context_version(void); +#else +#define smp_new_mmu_context_version() do { } while (0) +#endif + extern int init_new_context(struct task_struct *tsk, struct mm_struct *mm); extern void destroy_context(struct mm_struct *mm); @@ -58,21 +64,17 @@ extern void smp_tsb_sync(struct mm_struct *mm); extern void __flush_tlb_mm(unsigned long, unsigned long); -/* Switch the current MM context. */ +/* Switch the current MM context. Interrupts are disabled. */ static inline void switch_mm(struct mm_struct *old_mm, struct mm_struct *mm, struct task_struct *tsk) { unsigned long ctx_valid; int cpu; - /* Note: page_table_lock is used here to serialize switch_mm - * and activate_mm, and their calls to get_new_mmu_context. - * This use of page_table_lock is unrelated to its other uses. - */ - spin_lock(&mm->page_table_lock); + spin_lock(&mm->context.lock); ctx_valid = CTX_VALID(mm->context); if (!ctx_valid) get_new_mmu_context(mm); - spin_unlock(&mm->page_table_lock); + spin_unlock(&mm->context.lock); if (!ctx_valid || (old_mm != mm)) { load_secondary_context(mm); @@ -98,19 +100,16 @@ static inline void switch_mm(struct mm_struct *old_mm, struct mm_struct *mm, str /* Activate a new MM instance for the current task. */ static inline void activate_mm(struct mm_struct *active_mm, struct mm_struct *mm) { + unsigned long flags; int cpu; - /* Note: page_table_lock is used here to serialize switch_mm - * and activate_mm, and their calls to get_new_mmu_context. - * This use of page_table_lock is unrelated to its other uses. - */ - spin_lock(&mm->page_table_lock); + spin_lock_irqsave(&mm->context.lock, flags); if (!CTX_VALID(mm->context)) get_new_mmu_context(mm); cpu = smp_processor_id(); if (!cpu_isset(cpu, mm->cpu_vm_mask)) cpu_set(cpu, mm->cpu_vm_mask); - spin_unlock(&mm->page_table_lock); + spin_unlock_irqrestore(&mm->context.lock, flags); load_secondary_context(mm); __flush_tlb_mm(CTX_HWBITS(mm->context), SECONDARY_CONTEXT); -- cgit v1.2.2 From 36344762396ca868d6076c41a84bda25f1ed9d3c Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sat, 25 Feb 2006 17:16:29 -0800 Subject: [SPARC64]: Niagara optimized XOR functions for RAID. Signed-off-by: David S. Miller --- include/asm-sparc64/xor.h | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/asm-sparc64/xor.h b/include/asm-sparc64/xor.h index 8b3a7e4b60..8ce3f1813e 100644 --- a/include/asm-sparc64/xor.h +++ b/include/asm-sparc64/xor.h @@ -2,9 +2,11 @@ * include/asm-sparc64/xor.h * * High speed xor_block operation for RAID4/5 utilizing the - * UltraSparc Visual Instruction Set. + * UltraSparc Visual Instruction Set and Niagara block-init + * twin-load instructions. * * Copyright (C) 1997, 1999 Jakub Jelinek (jj@ultra.linux.cz) + * Copyright (C) 2006 David S. Miller * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,8 +18,7 @@ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include -#include +#include extern void xor_vis_2(unsigned long, unsigned long *, unsigned long *); extern void xor_vis_3(unsigned long, unsigned long *, unsigned long *, @@ -37,4 +38,29 @@ static struct xor_block_template xor_block_VIS = { .do_5 = xor_vis_5, }; -#define XOR_TRY_TEMPLATES xor_speed(&xor_block_VIS) +extern void xor_niagara_2(unsigned long, unsigned long *, unsigned long *); +extern void xor_niagara_3(unsigned long, unsigned long *, unsigned long *, + unsigned long *); +extern void xor_niagara_4(unsigned long, unsigned long *, unsigned long *, + unsigned long *, unsigned long *); +extern void xor_niagara_5(unsigned long, unsigned long *, unsigned long *, + unsigned long *, unsigned long *, unsigned long *); + +static struct xor_block_template xor_block_niagara = { + .name = "Niagara", + .do_2 = xor_niagara_2, + .do_3 = xor_niagara_3, + .do_4 = xor_niagara_4, + .do_5 = xor_niagara_5, +}; + +#undef XOR_TRY_TEMPLATES +#define XOR_TRY_TEMPLATES \ + do { \ + xor_speed(&xor_block_VIS); \ + xor_speed(&xor_block_niagara); \ + } while (0) + +/* For VIS for everything except Niagara. */ +#define XOR_SELECT_TEMPLATE(FASTEST) \ + (tlb_type == hypervisor ? &xor_block_niagara : &xor_block_VIS) -- cgit v1.2.2 From 97c4b6f95afadea5846b78ce589d25de2a245c56 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 26 Feb 2006 20:37:41 -0800 Subject: [SPARC64]: Use 13-bit context size always. We no longer have the problems that require using the smaller sizes. Signed-off-by: David S. Miller --- include/asm-sparc64/mmu.h | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) (limited to 'include') diff --git a/include/asm-sparc64/mmu.h b/include/asm-sparc64/mmu.h index 1504d303a1..da14a9bf0e 100644 --- a/include/asm-sparc64/mmu.h +++ b/include/asm-sparc64/mmu.h @@ -6,19 +6,7 @@ #include #include -/* - * For the 8k pagesize kernel, use only 10 hw context bits to optimize some - * shifts in the fast tlbmiss handlers, instead of all 13 bits (specifically - * for vpte offset calculation). For other pagesizes, this optimization in - * the tlbhandlers can not be done; but still, all 13 bits can not be used - * because the tlb handlers use "andcc" instruction which sign extends 13 - * bit arguments. - */ -#if PAGE_SHIFT == 13 -#define CTX_NR_BITS 10 -#else -#define CTX_NR_BITS 12 -#endif +#define CTX_NR_BITS 13 #define TAG_CONTEXT_BITS ((_AC(1,UL) << CTX_NR_BITS) - _AC(1,UL)) -- cgit v1.2.2 From b830ab665ad96c6b20d51a89b35cbc09ab5a2c29 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 28 Feb 2006 15:10:26 -0800 Subject: [SPARC64]: Fix bugs in SUN4V cpu mondo dispatch. There were several bugs in the SUN4V cpu mondo dispatch code. In fact, if we ever got a EWOULDBLOCK or other error from the hypervisor call, we'd potentially send a cpu mondo multiple times to the same cpu and even worse we could loop until the timeout resending the same mondo over and over to such cpus. So let's bulletproof this thing as follows: 1) Implement cpu_mondo_send() and cpu_state() hypervisor calls in arch/sparc64/kernel/entry.S, add prototypes to asm/hypervisor.h 2) Don't build and update the cpulist using inline functions, this was causing the cpu mask to not get updated in the caller. 3) Disable interrupts during the entire mondo send, otherwise our cpu list and/or mondo block could get overwritten if we take an interrupt and do a cpu mondo send on the current cpu. 4) Check for all possible error return types from the cpu_mondo_send() hypervisor call. In particular: HV_EOK) Our work is done, all cpus have received the mondo. HV_CPUERROR) One or more of the cpus in the cpu list we passed to the hypervisor are in error state. Use cpu_state() calls over the entries in the cpu list to see which ones. Record them in "error_mask" and report this after we are done sending the mondo to cpus which are not in error state. HV_EWOULDBLOCK) We need to keep trying. Any other error we consider fatal, we report the event and exit immediately. 5) We only timeout if forward progress is not made. Forward progress is defined as having at least one cpu get the mondo successfully in a given cpu_mondo_send() call. Otherwise we bump a counter and delay a little. If the counter hits a limit, we signal an error and report the event. Also, smp_call_function_mask() error handling reports the number of cpus incorrectly. Signed-off-by: David S. Miller --- include/asm-sparc64/hypervisor.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'include') diff --git a/include/asm-sparc64/hypervisor.h b/include/asm-sparc64/hypervisor.h index 726e2ea03c..612bf31975 100644 --- a/include/asm-sparc64/hypervisor.h +++ b/include/asm-sparc64/hypervisor.h @@ -342,6 +342,8 @@ extern unsigned long sun4v_cpu_qconf(unsigned long type, * ENOCPU Invalid cpu in CPU list * EWOULDBLOCK Some or all of the listed CPUs did not receive * the mondo + * ECPUERROR One or more of the listed CPUs are in error + * state, use HV_FAST_CPU_STATE to see which ones * EINVAL CPU list includes caller's CPU ID * * Send a mondo interrupt to the CPUs in the given CPU list with the @@ -355,6 +357,10 @@ extern unsigned long sun4v_cpu_qconf(unsigned long type, */ #define HV_FAST_CPU_MONDO_SEND 0x42 +#ifndef __ASSEMBLY__ +extern unsigned long sun4v_cpu_mondo_send(unsigned long cpu_count, unsigned long cpu_list_pa, unsigned long mondo_block_pa); +#endif + /* cpu_myid() * TRAP: HV_FAST_TRAP * FUNCTION: HV_FAST_CPU_MYID @@ -382,6 +388,10 @@ extern unsigned long sun4v_cpu_qconf(unsigned long type, #define HV_CPU_STATE_RUNNING 0x02 #define HV_CPU_STATE_ERROR 0x03 +#ifndef __ASSEMBLY__ +extern long sun4v_cpu_state(unsigned long cpuid); +#endif + /* cpu_set_rtba() * TRAP: HV_FAST_TRAP * FUNCTION: HV_FAST_CPU_SET_RTBA -- cgit v1.2.2 From e22990451a6a6263250cdd267708548dfa08a8f2 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 1 Mar 2006 22:25:43 -0800 Subject: [SPARC64]: Kill bogus function externs in asm/pgtable.h These are all implemented inline earlier in the file. Signed-off-by: David S. Miller --- include/asm-sparc64/pgtable.h | 24 ------------------------ 1 file changed, 24 deletions(-) (limited to 'include') diff --git a/include/asm-sparc64/pgtable.h b/include/asm-sparc64/pgtable.h index 6c8126b2de..75a2cd2d7e 100644 --- a/include/asm-sparc64/pgtable.h +++ b/include/asm-sparc64/pgtable.h @@ -646,27 +646,6 @@ static inline unsigned long pte_present(pte_t pte) /* Same in both SUN4V and SUN4U. */ #define pte_none(pte) (!pte_val(pte)) -extern unsigned long pte_present(pte_t); - -/* The following only work if pte_present() is true. - * Undefined behaviour if not.. - */ -extern unsigned long pte_read(pte_t); -extern unsigned long pte_exec(pte_t); -extern unsigned long pte_write(pte_t); -extern unsigned long pte_dirty(pte_t); -extern unsigned long pte_young(pte_t); -extern pte_t pte_wrprotect(pte_t); -extern pte_t pte_rdprotect(pte_t); -extern pte_t pte_mkclean(pte_t); -extern pte_t pte_mkold(pte_t); - -/* Be very careful when you change these three, they are delicate. */ -extern pte_t pte_mkyoung(pte_t); -extern pte_t pte_mkwrite(pte_t); -extern pte_t pte_mkdirty(pte_t); -extern pte_t pte_mkhuge(pte_t); - /* to find an entry in a page-table-directory. */ #define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1)) #define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address)) @@ -766,9 +745,6 @@ extern int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long from, unsigned long pfn, unsigned long size, pgprot_t prot); -/* Clear virtual and physical cachability, set side-effect bit. */ -extern pgprot_t pgprot_noncached(pgprot_t); - /* * For sparc32&64, the pfn in io_remap_pfn_range() carries in * its high 4 bits. These macros/functions put it there or get it from there. -- cgit v1.2.2 From 8bcd17411643beb9a601e032d0cf1016909a81d3 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 2 Mar 2006 18:12:27 -0800 Subject: [SPARC64]: Do not allow mapping pages within 4GB of 64-bit VA hole. The UltraSPARC T1 manual recommends this because the chip could instruction prefetch into the VA hole, and this would also make decoding certain kinds of memory access traps more difficult (because the chip sign extends certain pieces of trap state). Signed-off-by: David S. Miller --- include/asm-sparc64/a.out.h | 4 +++- include/asm-sparc64/page.h | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/asm-sparc64/a.out.h b/include/asm-sparc64/a.out.h index 02af289e3f..faac321d55 100644 --- a/include/asm-sparc64/a.out.h +++ b/include/asm-sparc64/a.out.h @@ -95,7 +95,9 @@ struct relocation_info /* used when header.a_machtype == M_SPARC */ #ifdef __KERNEL__ -#define STACK_TOP (test_thread_flag(TIF_32BIT) ? 0xf0000000 : 0x80000000000L) +#define STACK_TOP (test_thread_flag(TIF_32BIT) ? \ + 0xf0000000 : \ + (0x0000080000000000UL - (1UL << 32UL))) #endif diff --git a/include/asm-sparc64/page.h b/include/asm-sparc64/page.h index 5426bb28a9..c277ac56b9 100644 --- a/include/asm-sparc64/page.h +++ b/include/asm-sparc64/page.h @@ -107,7 +107,8 @@ typedef unsigned long pgprot_t; #endif #define TASK_UNMAPPED_BASE (test_thread_flag(TIF_32BIT) ? \ - (_AC(0x0000000070000000,UL)) : (PAGE_OFFSET)) + (_AC(0x0000000070000000,UL)) : \ + (_AC(0xfffff80000000000,UL) + (1UL << 32UL))) #endif /* !(__ASSEMBLY__) */ -- cgit v1.2.2 From a77754b4d0731321db266c6c60ffcd7c62757da5 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 6 Mar 2006 19:59:50 -0800 Subject: [SPARC64]: Bulletproof MMU context locking. 1) Always spin_lock_init() in init_context(). The caller essentially clears it out, or copies the mm info from the parent. In both cases we need to explicitly initialize the spinlock. 2) Always do explicit IRQ disabling while taking mm->context.lock and ctx_alloc_lock. Signed-off-by: David S. Miller --- include/asm-sparc64/mmu_context.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/asm-sparc64/mmu_context.h b/include/asm-sparc64/mmu_context.h index 4be40c58e3..ca36ea96f6 100644 --- a/include/asm-sparc64/mmu_context.h +++ b/include/asm-sparc64/mmu_context.h @@ -67,14 +67,14 @@ extern void __flush_tlb_mm(unsigned long, unsigned long); /* Switch the current MM context. Interrupts are disabled. */ static inline void switch_mm(struct mm_struct *old_mm, struct mm_struct *mm, struct task_struct *tsk) { - unsigned long ctx_valid; + unsigned long ctx_valid, flags; int cpu; - spin_lock(&mm->context.lock); + spin_lock_irqsave(&mm->context.lock, flags); ctx_valid = CTX_VALID(mm->context); if (!ctx_valid) get_new_mmu_context(mm); - spin_unlock(&mm->context.lock); + spin_unlock_irqrestore(&mm->context.lock, flags); if (!ctx_valid || (old_mm != mm)) { load_secondary_context(mm); -- cgit v1.2.2 From ee29074d3bd23848905f52c515974e0cd0219faa Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 6 Mar 2006 22:50:44 -0800 Subject: [SPARC64]: Fix new context version SMP handling. Don't piggy back the SMP receive signal code to do the context version change handling. Instead allocate another fixed PIL number for this asynchronous cross-call. We can't use smp_call_function() because this thing is invoked with interrupts disabled and a few spinlocks held. Also, fix smp_call_function_mask() to count "cpus" correctly. There is no guarentee that the local cpu is in the mask yet that is exactly what this code was assuming. Signed-off-by: David S. Miller --- include/asm-sparc64/pil.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/asm-sparc64/pil.h b/include/asm-sparc64/pil.h index 8f87750c35..79f827eb3f 100644 --- a/include/asm-sparc64/pil.h +++ b/include/asm-sparc64/pil.h @@ -16,11 +16,13 @@ #define PIL_SMP_CALL_FUNC 1 #define PIL_SMP_RECEIVE_SIGNAL 2 #define PIL_SMP_CAPTURE 3 +#define PIL_SMP_CTX_NEW_VERSION 4 #ifndef __ASSEMBLY__ #define PIL_RESERVED(PIL) ((PIL) == PIL_SMP_CALL_FUNC || \ (PIL) == PIL_SMP_RECEIVE_SIGNAL || \ - (PIL) == PIL_SMP_CAPTURE) + (PIL) == PIL_SMP_CAPTURE || \ + (PIL) == PIL_SMP_CTX_NEW_VERSION) #endif #endif /* !(_SPARC64_PIL_H) */ -- cgit v1.2.2 From d1112018b4bc82adf5c8a9c15a08954328f023ae Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 8 Mar 2006 02:16:07 -0800 Subject: [SPARC64]: Move over to sparsemem. This has been pending for a long time, and the fact that we waste a ton of ram on some configurations kind of pushed things over the edge. Signed-off-by: David S. Miller --- include/asm-sparc64/numnodes.h | 6 ++++++ include/asm-sparc64/page.h | 9 +-------- include/asm-sparc64/pgtable.h | 3 --- include/asm-sparc64/sparsemem.h | 12 ++++++++++++ 4 files changed, 19 insertions(+), 11 deletions(-) create mode 100644 include/asm-sparc64/numnodes.h create mode 100644 include/asm-sparc64/sparsemem.h (limited to 'include') diff --git a/include/asm-sparc64/numnodes.h b/include/asm-sparc64/numnodes.h new file mode 100644 index 0000000000..017e7e74f5 --- /dev/null +++ b/include/asm-sparc64/numnodes.h @@ -0,0 +1,6 @@ +#ifndef _SPARC64_NUMNODES_H +#define _SPARC64_NUMNODES_H + +#define NODES_SHIFT 0 + +#endif /* !(_SPARC64_NUMNODES_H) */ diff --git a/include/asm-sparc64/page.h b/include/asm-sparc64/page.h index c277ac56b9..f6b49256fe 100644 --- a/include/asm-sparc64/page.h +++ b/include/asm-sparc64/page.h @@ -125,17 +125,10 @@ typedef unsigned long pgprot_t; #define __pa(x) ((unsigned long)(x) - PAGE_OFFSET) #define __va(x) ((void *)((unsigned long) (x) + PAGE_OFFSET)) -/* PFNs are real physical page numbers. However, mem_map only begins to record - * per-page information starting at pfn_base. This is to handle systems where - * the first physical page in the machine is at some huge physical address, - * such as 4GB. This is common on a partitioned E10000, for example. - */ -extern struct page *pfn_to_page(unsigned long pfn); -extern unsigned long page_to_pfn(struct page *); +#define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT) #define virt_to_page(kaddr) pfn_to_page(__pa(kaddr)>>PAGE_SHIFT) -#define pfn_valid(pfn) (((pfn)-(pfn_base)) < max_mapnr) #define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT) #define virt_to_phys __pa diff --git a/include/asm-sparc64/pgtable.h b/include/asm-sparc64/pgtable.h index 75a2cd2d7e..d427ce6492 100644 --- a/include/asm-sparc64/pgtable.h +++ b/include/asm-sparc64/pgtable.h @@ -217,9 +217,6 @@ extern unsigned long pg_iobits; extern unsigned long _PAGE_ALL_SZ_BITS; extern unsigned long _PAGE_SZBITS; -extern unsigned long phys_base; -extern unsigned long pfn_base; - extern struct page *mem_map_zero; #define ZERO_PAGE(vaddr) (mem_map_zero) diff --git a/include/asm-sparc64/sparsemem.h b/include/asm-sparc64/sparsemem.h new file mode 100644 index 0000000000..ed5c9d8541 --- /dev/null +++ b/include/asm-sparc64/sparsemem.h @@ -0,0 +1,12 @@ +#ifndef _SPARC64_SPARSEMEM_H +#define _SPARC64_SPARSEMEM_H + +#ifdef __KERNEL__ + +#define SECTION_SIZE_BITS 26 +#define MAX_PHYSADDR_BITS 42 +#define MAX_PHYSMEM_BITS 42 + +#endif /* !(__KERNEL__) */ + +#endif /* !(_SPARC64_SPARSEMEM_H) */ -- cgit v1.2.2 From 8935dced547afbf37d0fcfcac9a3556494e53104 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 8 Mar 2006 16:09:19 -0800 Subject: [SPARC64]: Add SMT scheduling support for Niagara. The mapping is a simple "(cpuid >> 2) == core" for now. Later we'll add more sophisticated code that will walk the sun4v machine description and figure this out from there. We should also add core mappings for jaguar and panther processors. Signed-off-by: David S. Miller --- include/asm-sparc64/smp.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/asm-sparc64/smp.h b/include/asm-sparc64/smp.h index ad1d35a7d1..89d86ecaab 100644 --- a/include/asm-sparc64/smp.h +++ b/include/asm-sparc64/smp.h @@ -33,6 +33,8 @@ extern cpumask_t phys_cpu_present_map; #define cpu_possible_map phys_cpu_present_map +extern cpumask_t cpu_sibling_map[NR_CPUS]; + /* * General functions that each host system must provide. */ -- cgit v1.2.2 From 90a6646bf6a1ca821f32d5510e935855612904df Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 8 Mar 2006 17:18:19 -0800 Subject: [SPARC64]: Fix system type in /proc/cpuinfo and remove bogus OBP check. Report 'sun4v' when appropriate in /proc/cpuinfo Remove all the verifications of the OBP version string. Just make sure it's there, and report it raw in the bootup logs and via /proc/cpuinfo. Signed-off-by: David S. Miller --- include/asm-sparc64/oplib.h | 23 ++--------------------- 1 file changed, 2 insertions(+), 21 deletions(-) (limited to 'include') diff --git a/include/asm-sparc64/oplib.h b/include/asm-sparc64/oplib.h index 84618f8a9e..c754676e13 100644 --- a/include/asm-sparc64/oplib.h +++ b/include/asm-sparc64/oplib.h @@ -12,18 +12,8 @@ #include #include -/* Enumeration to describe the prom major version we have detected. */ -enum prom_major_version { - PROM_V0, /* Original sun4c V0 prom */ - PROM_V2, /* sun4c and early sun4m V2 prom */ - PROM_V3, /* sun4m and later, up to sun4d/sun4e machines V3 */ - PROM_P1275, /* IEEE compliant ISA based Sun PROM, only sun4u */ - PROM_AP1000, /* actually no prom at all */ -}; - -extern enum prom_major_version prom_vers; -/* Revision, and firmware revision. */ -extern unsigned int prom_rev, prom_prev; +/* OBP version string. */ +extern char prom_version[]; /* Root node of the prom device tree, this stays constant after * initialization is complete. @@ -133,15 +123,6 @@ extern void prom_setcallback(callback_func_t func_ptr); */ extern unsigned char prom_get_idprom(char *idp_buffer, int idpbuf_size); -/* Get the prom major version. */ -extern int prom_version(void); - -/* Get the prom plugin revision. */ -extern int prom_getrev(void); - -/* Get the prom firmware revision. */ -extern int prom_getprev(void); - /* Character operations to/from the console.... */ /* Non-blocking get character from console. */ -- cgit v1.2.2 From 7a1ac5264108fc3ed22d17a3cdd76212ed1666d1 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 16 Mar 2006 02:02:32 -0800 Subject: [SPARC64]: Fix and re-enable dynamic TSB sizing. This is good for up to %50 performance improvement of some test cases. The problem has been the race conditions, and hopefully I've plugged them all up here. 1) There was a serious race in switch_mm() wrt. lazy TLB switching to and from kernel threads. We could erroneously skip a tsb_context_switch() and thus use a stale TSB across a TSB grow event. There is a big comment now in that function describing exactly how it can happen. 2) All code paths that do something with the TSB need to be guarded with the mm->context.lock spinlock. This makes page table flushing paths properly synchronize with both TSB growing and TLB context changes. 3) TSB growing events are moved to the end of successful fault processing. Previously it was in update_mmu_cache() but that is deadlock prone. At the end of do_sparc64_fault() we hold no spinlocks that could deadlock the TSB grow sequence. We also have dropped the address space semaphore. While we're here, add prefetching to the copy_tsb() routine and put it in assembler into the tsb.S file. This piece of code is quite time critical. There are some small negative side effects to this code which can be improved upon. In particular we grab the mm->context.lock even for the tsb insert done by update_mmu_cache() now and that's a bit excessive. We can get rid of that locking, and the same lock taking in flush_tsb_user(), by disabling PSTATE_IE around the whole operation including the capturing of the tsb pointer and tsb_nentries value. That would work because anyone growing the TSB won't free up the old TSB until all cpus respond to the TSB change cross call. I'm not quite so confident in that optimization to put it in right now, but eventually we might be able to and the description is here for reference. This code seems very solid now. It passes several parallel GCC bootstrap builds, and our favorite "nut cruncher" stress test which is a full "make -j8192" build of a "make allmodconfig" kernel. That puts about 256 processes on each cpu's run queue, makes lots of process cpu migrations occur, causes lots of page table and TLB flushing activity, incurs many context version number changes, and it swaps the machine real far out to disk even though there is 16GB of ram on this test system. :-) Signed-off-by: David S. Miller --- include/asm-sparc64/mmu_context.h | 50 +++++++++++++++++++++++++++++---------- 1 file changed, 38 insertions(+), 12 deletions(-) (limited to 'include') diff --git a/include/asm-sparc64/mmu_context.h b/include/asm-sparc64/mmu_context.h index ca36ea96f6..e7974321d0 100644 --- a/include/asm-sparc64/mmu_context.h +++ b/include/asm-sparc64/mmu_context.h @@ -42,7 +42,7 @@ static inline void tsb_context_switch(struct mm_struct *mm) __pa(&mm->context.tsb_descr)); } -extern void tsb_grow(struct mm_struct *mm, unsigned long mm_rss, gfp_t gfp_flags); +extern void tsb_grow(struct mm_struct *mm, unsigned long mm_rss); #ifdef CONFIG_SMP extern void smp_tsb_sync(struct mm_struct *mm); #else @@ -74,18 +74,43 @@ static inline void switch_mm(struct mm_struct *old_mm, struct mm_struct *mm, str ctx_valid = CTX_VALID(mm->context); if (!ctx_valid) get_new_mmu_context(mm); - spin_unlock_irqrestore(&mm->context.lock, flags); - if (!ctx_valid || (old_mm != mm)) { - load_secondary_context(mm); - tsb_context_switch(mm); - } + /* We have to be extremely careful here or else we will miss + * a TSB grow if we switch back and forth between a kernel + * thread and an address space which has it's TSB size increased + * on another processor. + * + * It is possible to play some games in order to optimize the + * switch, but the safest thing to do is to unconditionally + * perform the secondary context load and the TSB context switch. + * + * For reference the bad case is, for address space "A": + * + * CPU 0 CPU 1 + * run address space A + * set cpu0's bits in cpu_vm_mask + * switch to kernel thread, borrow + * address space A via entry_lazy_tlb + * run address space A + * set cpu1's bit in cpu_vm_mask + * flush_tlb_pending() + * reset cpu_vm_mask to just cpu1 + * TSB grow + * run address space A + * context was valid, so skip + * TSB context switch + * + * At that point cpu0 continues to use a stale TSB, the one from + * before the TSB grow performed on cpu1. cpu1 did not cross-call + * cpu0 to update it's TSB because at that point the cpu_vm_mask + * only had cpu1 set in it. + */ + load_secondary_context(mm); + tsb_context_switch(mm); - /* Even if (mm == old_mm) we _must_ check - * the cpu_vm_mask. If we do not we could - * corrupt the TLB state because of how - * smp_flush_tlb_{page,range,mm} on sparc64 - * and lazy tlb switches work. -DaveM + /* Any time a processor runs a context on an address space + * for the first time, we must flush that context out of the + * local TLB. */ cpu = smp_processor_id(); if (!ctx_valid || !cpu_isset(cpu, mm->cpu_vm_mask)) { @@ -93,6 +118,7 @@ static inline void switch_mm(struct mm_struct *old_mm, struct mm_struct *mm, str __flush_tlb_mm(CTX_HWBITS(mm->context), SECONDARY_CONTEXT); } + spin_unlock_irqrestore(&mm->context.lock, flags); } #define deactivate_mm(tsk,mm) do { } while (0) @@ -109,11 +135,11 @@ static inline void activate_mm(struct mm_struct *active_mm, struct mm_struct *mm cpu = smp_processor_id(); if (!cpu_isset(cpu, mm->cpu_vm_mask)) cpu_set(cpu, mm->cpu_vm_mask); - spin_unlock_irqrestore(&mm->context.lock, flags); load_secondary_context(mm); __flush_tlb_mm(CTX_HWBITS(mm->context), SECONDARY_CONTEXT); tsb_context_switch(mm); + spin_unlock_irqrestore(&mm->context.lock, flags); } #endif /* !(__ASSEMBLY__) */ -- cgit v1.2.2 From a91690ddd05ab0b7fbdd37733875525ac75c20f2 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 17 Mar 2006 14:41:03 -0800 Subject: [SPARC64]: Top-down address space allocation for 32-bit tasks. Currently allocations are very constrained for 32-bit processes. It grows down-up from 0x70000000 to 0xf0000000 which gives about 2GB of stack + dynamic mmap() space. So support the top-down method, and we need to override the generic helper function in order to deal with D-cache coloring. With these changes I was able to squeeze out a mmap() just over 3.6GB in size in a 32-bit process. Signed-off-by: David S. Miller --- include/asm-sparc64/pgtable.h | 5 ++++- include/asm-sparc64/processor.h | 2 ++ 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/asm-sparc64/pgtable.h b/include/asm-sparc64/pgtable.h index d427ce6492..ed4124edf8 100644 --- a/include/asm-sparc64/pgtable.h +++ b/include/asm-sparc64/pgtable.h @@ -752,8 +752,11 @@ extern int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long from, #include -/* We provide our own get_unmapped_area to cope with VA holes for userland */ +/* We provide our own get_unmapped_area to cope with VA holes and + * SHM area cache aliasing for userland. + */ #define HAVE_ARCH_UNMAPPED_AREA +#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN /* We provide a special get_unmapped_area for framebuffer mmaps to try and use * the largest alignment possible such that larget PTEs can be used. diff --git a/include/asm-sparc64/processor.h b/include/asm-sparc64/processor.h index 685479fb43..c6896b8828 100644 --- a/include/asm-sparc64/processor.h +++ b/include/asm-sparc64/processor.h @@ -217,6 +217,8 @@ static inline void prefetchw(const void *x) #define spin_lock_prefetch(x) prefetchw(x) +#define HAVE_ARCH_PICK_MMAP_LAYOUT + #endif /* !(__ASSEMBLY__) */ #endif /* !(__ASM_SPARC64_PROCESSOR_H) */ -- cgit v1.2.2 From d61e16df940e02e25679bdc1aee8c25786f6de90 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 17 Mar 2006 17:33:56 -0800 Subject: [SPARC64]: Increase top of 32-bit process stack. Put it one page below the top of the 32-bit address space. This gives us ~16MB more address space to work with. Signed-off-by: David S. Miller --- include/asm-sparc64/a.out.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/asm-sparc64/a.out.h b/include/asm-sparc64/a.out.h index faac321d55..35cb5c9e0c 100644 --- a/include/asm-sparc64/a.out.h +++ b/include/asm-sparc64/a.out.h @@ -95,9 +95,11 @@ struct relocation_info /* used when header.a_machtype == M_SPARC */ #ifdef __KERNEL__ +#define STACK_TOP32 ((1UL << 32UL) - PAGE_SIZE) +#define STACK_TOP64 (0x0000080000000000UL - (1UL << 32UL)) + #define STACK_TOP (test_thread_flag(TIF_32BIT) ? \ - 0xf0000000 : \ - (0x0000080000000000UL - (1UL << 32UL))) + STACK_TOP32 : STACK_TOP64) #endif -- cgit v1.2.2 From bb8646d8340fa7c1b66a037428e39f85f8738f0a Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sat, 18 Mar 2006 23:55:11 -0800 Subject: [SPARC64]: Optimized TSB table initialization. We only need to write an invalid tag every 16 bytes, so taking advantage of this can save many instructions compared to the simple memset() call we make now. A prefetching implementation is implemented for sun4u and a block-init store version if implemented for Niagara. The next trick is to be able to perform an init and a copy_tsb() in parallel when growing a TSB table. Signed-off-by: David S. Miller --- include/asm-sparc64/mmu.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/asm-sparc64/mmu.h b/include/asm-sparc64/mmu.h index da14a9bf0e..230ba678d3 100644 --- a/include/asm-sparc64/mmu.h +++ b/include/asm-sparc64/mmu.h @@ -88,6 +88,7 @@ struct tsb { extern void __tsb_insert(unsigned long ent, unsigned long tag, unsigned long pte); extern void tsb_flush(unsigned long ent, unsigned long tag); +extern void tsb_init(struct tsb *tsb, unsigned long size); typedef struct { spinlock_t lock; -- cgit v1.2.2 From f6b83f070e9b7ad9075f7cc5646260e56c7d0219 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 20 Mar 2006 01:17:17 -0800 Subject: [SPARC64]: Fix 2 bugs in huge page support. 1) huge_pte_offset() did not check the page table hierarchy elements as being empty correctly, resulting in an OOPS 2) Need platform specific hugetlb_get_unmapped_area() to handle the top-down vs. bottom-up address space allocation strategies. Signed-off-by: David S. Miller --- include/asm-sparc64/page.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/asm-sparc64/page.h b/include/asm-sparc64/page.h index f6b49256fe..fcb2812265 100644 --- a/include/asm-sparc64/page.h +++ b/include/asm-sparc64/page.h @@ -104,6 +104,7 @@ typedef unsigned long pgprot_t; #define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT) #define ARCH_HAS_SETCLEAR_HUGE_PTE #define ARCH_HAS_HUGETLB_PREFAULT_HOOK +#define HAVE_ARCH_HUGETLB_UNMAPPED_AREA #endif #define TASK_UNMAPPED_BASE (test_thread_flag(TIF_32BIT) ? \ -- cgit v1.2.2 From 7abe53155b77c31028a7158883bc9aac705790da Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 20 Mar 2006 10:12:31 +0000 Subject: [ARM] Fix cosmetic typo in asm/irq.h The IRQ resource flags are IORESOURCE_IRQ not IRQRESOURCE_IRQ. Signed-off-by: Russell King --- include/asm-arm/irq.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/asm-arm/irq.h b/include/asm-arm/irq.h index 7772432d3f..60b5105c9c 100644 --- a/include/asm-arm/irq.h +++ b/include/asm-arm/irq.h @@ -27,7 +27,7 @@ extern void enable_irq(unsigned int); /* * These correspond with the SA_TRIGGER_* defines, and therefore the - * IRQRESOURCE_IRQ_* defines. + * IORESOURCE_IRQ_* defines. */ #define __IRQT_RISEDGE (1 << 0) #define __IRQT_FALEDGE (1 << 1) -- cgit v1.2.2 From 33b9b3ee9709b19c4f02ab91571d53540d05c3d1 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Mon, 30 Jan 2006 14:29:21 -0800 Subject: IB: Add userspace support for resizing CQs Add support to uverbs to handle resizing userspace CQs (completion queues), including adding an ABI for marshalling requests and responses. The kernel midlayer already has ib_resize_cq(). Signed-off-by: Roland Dreier --- include/rdma/ib_user_verbs.h | 13 ++++++++++++- include/rdma/ib_verbs.h | 5 +++-- 2 files changed, 15 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/rdma/ib_user_verbs.h b/include/rdma/ib_user_verbs.h index 5ff1490c08..6ad1207e42 100644 --- a/include/rdma/ib_user_verbs.h +++ b/include/rdma/ib_user_verbs.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2005 Topspin Communications. All rights reserved. - * Copyright (c) 2005 Cisco Systems. All rights reserved. + * Copyright (c) 2005, 2006 Cisco Systems. All rights reserved. * Copyright (c) 2005 PathScale, Inc. All rights reserved. * * This software is available to you under a choice of one of two @@ -265,6 +265,17 @@ struct ib_uverbs_create_cq_resp { __u32 cqe; }; +struct ib_uverbs_resize_cq { + __u64 response; + __u32 cq_handle; + __u32 cqe; + __u64 driver_data[0]; +}; + +struct ib_uverbs_resize_cq_resp { + __u32 cqe; +}; + struct ib_uverbs_poll_cq { __u64 response; __u32 cq_handle; diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h index 22fc886b96..38fa6c082e 100644 --- a/include/rdma/ib_verbs.h +++ b/include/rdma/ib_verbs.h @@ -5,7 +5,7 @@ * Copyright (c) 2004 Topspin Corporation. All rights reserved. * Copyright (c) 2004 Voltaire Corporation. All rights reserved. * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved. - * Copyright (c) 2005 Cisco Systems. All rights reserved. + * Copyright (c) 2005, 2006 Cisco Systems. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU @@ -880,7 +880,8 @@ struct ib_device { struct ib_ucontext *context, struct ib_udata *udata); int (*destroy_cq)(struct ib_cq *cq); - int (*resize_cq)(struct ib_cq *cq, int cqe); + int (*resize_cq)(struct ib_cq *cq, int cqe, + struct ib_udata *udata); int (*poll_cq)(struct ib_cq *cq, int num_entries, struct ib_wc *wc); int (*peek_cq)(struct ib_cq *cq, int wc_cnt); -- cgit v1.2.2 From c5bcbbb9fe00128d500c2f473d5ddc8d8c2c53a7 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Thu, 2 Feb 2006 09:47:14 -0800 Subject: IB: Allow userspace to set node description Expose a writable "node_desc" sysfs attribute for InfiniBand devices. This allows userspace to update the node description with information such as the node's hostname, so that IB network management software can tie its view to the real world. Signed-off-by: Michael S. Tsirkin Signed-off-by: Roland Dreier --- include/rdma/ib_verbs.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h index 38fa6c082e..1d31c8cd5c 100644 --- a/include/rdma/ib_verbs.h +++ b/include/rdma/ib_verbs.h @@ -222,11 +222,13 @@ struct ib_port_attr { }; enum ib_device_modify_flags { - IB_DEVICE_MODIFY_SYS_IMAGE_GUID = 1 + IB_DEVICE_MODIFY_SYS_IMAGE_GUID = 1 << 0, + IB_DEVICE_MODIFY_NODE_DESC = 1 << 1 }; struct ib_device_modify { u64 sys_image_guid; + char node_desc[64]; }; enum ib_port_modify_flags { @@ -951,6 +953,7 @@ struct ib_device { u64 uverbs_cmd_mask; int uverbs_abi_ver; + char node_desc[64]; __be64 node_guid; u8 node_type; u8 phys_port_cnt; -- cgit v1.2.2 From d36f34aadf184d8cc4c240de2b6319ccea8334bb Mon Sep 17 00:00:00 2001 From: Or Gerlitz Date: Thu, 2 Feb 2006 10:43:45 -0800 Subject: IB: Enable FMR pool user to set page size This patch allows the consumer to set the page size of "pages" mapped by the pool FMRs, which is a feature already existing in the base verbs API. On the cosmetic side it changes ib_fmr_attr.page_size field to be named page_shift. Signed-off-by: Or Gerlitz Signed-off-by: Roland Dreier --- include/rdma/ib_fmr_pool.h | 2 ++ include/rdma/ib_verbs.h | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/rdma/ib_fmr_pool.h b/include/rdma/ib_fmr_pool.h index 86b7e93f19..4ace54cd0c 100644 --- a/include/rdma/ib_fmr_pool.h +++ b/include/rdma/ib_fmr_pool.h @@ -43,6 +43,7 @@ struct ib_fmr_pool; /** * struct ib_fmr_pool_param - Parameters for creating FMR pool * @max_pages_per_fmr:Maximum number of pages per map request. + * @page_shift: Log2 of sizeof "pages" mapped by this fmr * @access:Access flags for FMRs in pool. * @pool_size:Number of FMRs to allocate for pool. * @dirty_watermark:Flush is triggered when @dirty_watermark dirty @@ -55,6 +56,7 @@ struct ib_fmr_pool; */ struct ib_fmr_pool_param { int max_pages_per_fmr; + int page_shift; enum ib_access_flags access; int pool_size; int dirty_watermark; diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h index 1d31c8cd5c..61a4390ae9 100644 --- a/include/rdma/ib_verbs.h +++ b/include/rdma/ib_verbs.h @@ -651,7 +651,7 @@ struct ib_mw_bind { struct ib_fmr_attr { int max_pages; int max_maps; - u8 page_size; + u8 page_shift; }; struct ib_ucontext { -- cgit v1.2.2 From 8a51866f08103ba04894ce0f65eef567ddc3ed40 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Mon, 13 Feb 2006 12:48:12 -0800 Subject: IB: Add ib_modify_qp_is_ok() library function The in-kernel mthca driver contains a table of which attributes are valid for each queue pair state transition. It turns out that both other IB drivers -- ipath and ehca -- which are being prepared for merging have copied this table, errors and all. To forestall this code duplication, move this table and the code to check parameters against it into a midlayer library function, ib_modify_qp_is_ok(). Signed-off-by: Roland Dreier --- include/rdma/ib_verbs.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'include') diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h index 61a4390ae9..010287c844 100644 --- a/include/rdma/ib_verbs.h +++ b/include/rdma/ib_verbs.h @@ -990,6 +990,24 @@ static inline int ib_copy_to_udata(struct ib_udata *udata, void *src, size_t len return copy_to_user(udata->outbuf, src, len) ? -EFAULT : 0; } +/** + * ib_modify_qp_is_ok - Check that the supplied attribute mask + * contains all required attributes and no attributes not allowed for + * the given QP state transition. + * @cur_state: Current QP state + * @next_state: Next QP state + * @type: QP type + * @mask: Mask of supplied QP attributes + * + * This function is a helper function that a low-level driver's + * modify_qp method can use to validate the consumer's input. It + * checks that cur_state and next_state are valid QP states, that a + * transition from cur_state to next_state is allowed by the IB spec, + * and that the attribute mask supplied is allowed for the transition. + */ +int ib_modify_qp_is_ok(enum ib_qp_state cur_state, enum ib_qp_state next_state, + enum ib_qp_type type, enum ib_qp_attr_mask mask); + int ib_register_event_handler (struct ib_event_handler *event_handler); int ib_unregister_event_handler(struct ib_event_handler *event_handler); void ib_dispatch_event(struct ib_event *event); -- cgit v1.2.2 From a74cd4af0bfa9578594acbb711a958104c93b772 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Mon, 13 Feb 2006 16:30:49 -0800 Subject: IB: Whitespace cleanups Remove trailing whitespace and fix indentation that with spaces instead of tabs. Signed-off-by: Roland Dreier --- include/rdma/ib_user_verbs.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/rdma/ib_user_verbs.h b/include/rdma/ib_user_verbs.h index 6ad1207e42..fb94c08169 100644 --- a/include/rdma/ib_user_verbs.h +++ b/include/rdma/ib_user_verbs.h @@ -426,7 +426,7 @@ struct ib_uverbs_sge { }; struct ib_uverbs_send_wr { - __u64 wr_id; + __u64 wr_id; __u32 num_sge; __u32 opcode; __u32 send_flags; @@ -500,7 +500,7 @@ struct ib_uverbs_post_srq_recv_resp { struct ib_uverbs_global_route { __u8 dgid[16]; - __u32 flow_label; + __u32 flow_label; __u8 sgid_index; __u8 hop_limit; __u8 traffic_class; -- cgit v1.2.2 From 7ccc9a24e01258a31ee2b964215e4ddddd2a02c4 Mon Sep 17 00:00:00 2001 From: Dotan Barak Date: Mon, 13 Feb 2006 16:31:25 -0800 Subject: IB/uverbs: Support for query QP from userspace Add support to uverbs to handle querying userspace QPs (queue pairs), including adding an ABI for marshalling requests and responses. The kernel midlayer already has the underlying ib_query_qp() function. Signed-off-by: Dotan Barak Signed-off-by: Roland Dreier --- include/rdma/ib_user_verbs.h | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) (limited to 'include') diff --git a/include/rdma/ib_user_verbs.h b/include/rdma/ib_user_verbs.h index fb94c08169..58662c34a3 100644 --- a/include/rdma/ib_user_verbs.h +++ b/include/rdma/ib_user_verbs.h @@ -370,6 +370,47 @@ struct ib_uverbs_qp_dest { __u8 port_num; }; +struct ib_uverbs_query_qp { + __u64 response; + __u32 qp_handle; + __u32 attr_mask; + __u64 driver_data[0]; +}; + +struct ib_uverbs_query_qp_resp { + struct ib_uverbs_qp_dest dest; + struct ib_uverbs_qp_dest alt_dest; + __u32 max_send_wr; + __u32 max_recv_wr; + __u32 max_send_sge; + __u32 max_recv_sge; + __u32 max_inline_data; + __u32 qkey; + __u32 rq_psn; + __u32 sq_psn; + __u32 dest_qp_num; + __u32 qp_access_flags; + __u16 pkey_index; + __u16 alt_pkey_index; + __u8 qp_state; + __u8 cur_qp_state; + __u8 path_mtu; + __u8 path_mig_state; + __u8 en_sqd_async_notify; + __u8 max_rd_atomic; + __u8 max_dest_rd_atomic; + __u8 min_rnr_timer; + __u8 port_num; + __u8 timeout; + __u8 retry_cnt; + __u8 rnr_retry; + __u8 alt_port_num; + __u8 alt_timeout; + __u8 sq_sig_all; + __u8 reserved[5]; + __u64 driver_data[0]; +}; + struct ib_uverbs_modify_qp { struct ib_uverbs_qp_dest dest; struct ib_uverbs_qp_dest alt_dest; -- cgit v1.2.2 From 8bdb0e8632e0f5061bd18b6934346cb609490135 Mon Sep 17 00:00:00 2001 From: Dotan Barak Date: Mon, 13 Feb 2006 16:31:57 -0800 Subject: IB/uverbs: Support for query SRQ from userspace Add support to uverbs to handle querying userspace SRQs (shared receive queues), including adding an ABI for marshalling requests and responses. The kernel midlayer already has the underlying ib_query_srq() function. Signed-off-by: Dotan Barak Signed-off-by: Roland Dreier --- include/rdma/ib_user_verbs.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'include') diff --git a/include/rdma/ib_user_verbs.h b/include/rdma/ib_user_verbs.h index 58662c34a3..0edd3a6fe8 100644 --- a/include/rdma/ib_user_verbs.h +++ b/include/rdma/ib_user_verbs.h @@ -2,6 +2,7 @@ * Copyright (c) 2005 Topspin Communications. All rights reserved. * Copyright (c) 2005, 2006 Cisco Systems. All rights reserved. * Copyright (c) 2005 PathScale, Inc. All rights reserved. + * Copyright (c) 2006 Mellanox Technologies. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU @@ -613,6 +614,20 @@ struct ib_uverbs_modify_srq { __u64 driver_data[0]; }; +struct ib_uverbs_query_srq { + __u64 response; + __u32 srq_handle; + __u32 reserved; + __u64 driver_data[0]; +}; + +struct ib_uverbs_query_srq_resp { + __u32 max_wr; + __u32 max_sge; + __u32 srq_limit; + __u32 reserved; +}; + struct ib_uverbs_destroy_srq { __u64 response; __u32 srq_handle; -- cgit v1.2.2 From 4d9781c5ce1a517a07dbf03c37323c011037fe79 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Thu, 16 Feb 2006 09:26:19 -0800 Subject: IB/uverbs: Fix alignment of struct ib_uverbs_create_qp_resp The size of struct ib_uverbs_create_qp_resp is not even multiple of 8 bytes. This causes problems for low-level drivers that add private data after the structure: 32-bit userspace will look in the wrong place for a response from a 64-bit kernel. Fix this by adding a reserved field. Also, bump the ABI version because this changes the size of a structure. Pointed out by Hoang-Nam Nguyen . Signed-off-by: Roland Dreier --- include/rdma/ib_user_verbs.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/rdma/ib_user_verbs.h b/include/rdma/ib_user_verbs.h index 0edd3a6fe8..3bf4402f46 100644 --- a/include/rdma/ib_user_verbs.h +++ b/include/rdma/ib_user_verbs.h @@ -44,7 +44,7 @@ * Increment this value if any changes that break userspace ABI * compatibility are made. */ -#define IB_USER_VERBS_ABI_VERSION 4 +#define IB_USER_VERBS_ABI_VERSION 5 enum { IB_USER_VERBS_CMD_GET_CONTEXT, @@ -350,6 +350,7 @@ struct ib_uverbs_create_qp_resp { __u32 max_send_sge; __u32 max_recv_sge; __u32 max_inline_data; + __u32 reserved; }; /* -- cgit v1.2.2 From abb6e9ba17eb133ab385d0f9017fa8afa809d52a Mon Sep 17 00:00:00 2001 From: Dotan Barak Date: Thu, 23 Feb 2006 12:13:51 -0800 Subject: IB/mthca: Return actual capacity from create_srq Have mthca's create_srq method return the actual capacity of the SRQ that gets created. Also update comments in to clarify that this is what is expected from ib_create_srq(). Signed-off-by: Dotan Barak Signed-off-by: Roland Dreier --- include/rdma/ib_verbs.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h index 010287c844..c1ad6273ac 100644 --- a/include/rdma/ib_verbs.h +++ b/include/rdma/ib_verbs.h @@ -1100,7 +1100,9 @@ int ib_destroy_ah(struct ib_ah *ah); * ib_create_srq - Creates a SRQ associated with the specified protection * domain. * @pd: The protection domain associated with the SRQ. - * @srq_init_attr: A list of initial attributes required to create the SRQ. + * @srq_init_attr: A list of initial attributes required to create the + * SRQ. If SRQ creation succeeds, then the attributes are updated to + * the actual capabilities of the created SRQ. * * srq_attr->max_wr and srq_attr->max_sge are read the determine the * requested size of the SRQ, and set to the actual values allocated @@ -1159,7 +1161,9 @@ static inline int ib_post_srq_recv(struct ib_srq *srq, * ib_create_qp - Creates a QP associated with the specified protection * domain. * @pd: The protection domain associated with the QP. - * @qp_init_attr: A list of initial attributes required to create the QP. + * @qp_init_attr: A list of initial attributes required to create the + * QP. If QP creation succeeds, then the attributes are updated to + * the actual capabilities of the created QP. */ struct ib_qp *ib_create_qp(struct ib_pd *pd, struct ib_qp_init_attr *qp_init_attr); -- cgit v1.2.2 From ea88fd16d6e85f4bc71b6053180b64f04be1ff14 Mon Sep 17 00:00:00 2001 From: Dotan Barak Date: Thu, 23 Feb 2006 12:36:18 -0800 Subject: IB/uverbs: Return actual capacity from create SRQ operation Pass actual capacity of created SRQ back to userspace, so that userspace can report accurate capacities. This requires an ABI bump, to change struct ib_uverbs_create_srq_resp. Signed-off-by: Dotan Barak Signed-off-by: Roland Dreier --- include/rdma/ib_user_verbs.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/rdma/ib_user_verbs.h b/include/rdma/ib_user_verbs.h index 3bf4402f46..338ed43330 100644 --- a/include/rdma/ib_user_verbs.h +++ b/include/rdma/ib_user_verbs.h @@ -44,7 +44,7 @@ * Increment this value if any changes that break userspace ABI * compatibility are made. */ -#define IB_USER_VERBS_ABI_VERSION 5 +#define IB_USER_VERBS_ABI_VERSION 6 enum { IB_USER_VERBS_CMD_GET_CONTEXT, @@ -605,6 +605,9 @@ struct ib_uverbs_create_srq { struct ib_uverbs_create_srq_resp { __u32 srq_handle; + __u32 max_wr; + __u32 max_sge; + __u32 reserved; }; struct ib_uverbs_modify_srq { -- cgit v1.2.2 From f36e1793e25513380cae5958a9164d4cc4458ad0 Mon Sep 17 00:00:00 2001 From: Jack Morgenstein Date: Fri, 3 Mar 2006 21:54:13 -0800 Subject: IB/umad: Add support for large RMPP transfers Add support for sending and receiving large RMPP transfers. The old code supports transfers only as large as a single contiguous kernel memory allocation. This patch uses linked list of memory buffers when sending and receiving data to avoid needing contiguous pages for larger transfers. Receive side: copy the arriving MADs in chunks instead of coalescing to one large buffer in kernel space. Send side: split a multipacket MAD buffer to a list of segments, (multipacket_list) and send these using a gather list of size 2. Also, save pointer to last sent segment, and retrieve requested segments by walking list starting at last sent segment. Finally, save pointer to last-acked segment. When retrying, retrieve segments for resending relative to this pointer. When updating last ack, start at this pointer. Signed-off-by: Jack Morgenstein Signed-off-by: Sean Hefty Signed-off-by: Roland Dreier --- include/rdma/ib_mad.h | 48 ++++++++++++++++++++++++++++++------------------ 1 file changed, 30 insertions(+), 18 deletions(-) (limited to 'include') diff --git a/include/rdma/ib_mad.h b/include/rdma/ib_mad.h index 2c13350674..51ab8eddb2 100644 --- a/include/rdma/ib_mad.h +++ b/include/rdma/ib_mad.h @@ -33,7 +33,7 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * - * $Id: ib_mad.h 2775 2005-07-02 13:42:12Z halr $ + * $Id: ib_mad.h 5596 2006-03-03 01:00:07Z sean.hefty $ */ #if !defined( IB_MAD_H ) @@ -208,15 +208,23 @@ struct ib_class_port_info /** * ib_mad_send_buf - MAD data buffer and work request for sends. * @next: A pointer used to chain together MADs for posting. - * @mad: References an allocated MAD data buffer. + * @mad: References an allocated MAD data buffer for MADs that do not have + * RMPP active. For MADs using RMPP, references the common and management + * class specific headers. * @mad_agent: MAD agent that allocated the buffer. * @ah: The address handle to use when sending the MAD. * @context: User-controlled context fields. + * @hdr_len: Indicates the size of the data header of the MAD. This length + * includes the common MAD, RMPP, and class specific headers. + * @data_len: Indicates the total size of user-transferred data. + * @seg_count: The number of RMPP segments allocated for this send. + * @seg_size: Size of each RMPP segment. * @timeout_ms: Time to wait for a response. * @retries: Number of times to retry a request for a response. * * Users are responsible for initializing the MAD buffer itself, with the - * exception of specifying the payload length field in any RMPP MAD. + * exception of any RMPP header. Additional segment buffer space allocated + * beyond data_len is padding. */ struct ib_mad_send_buf { struct ib_mad_send_buf *next; @@ -224,6 +232,10 @@ struct ib_mad_send_buf { struct ib_mad_agent *mad_agent; struct ib_ah *ah; void *context[2]; + int hdr_len; + int data_len; + int seg_count; + int seg_size; int timeout_ms; int retries; }; @@ -299,7 +311,7 @@ typedef void (*ib_mad_snoop_handler)(struct ib_mad_agent *mad_agent, * @mad_recv_wc: Received work completion information on the received MAD. * * MADs received in response to a send request operation will be handed to - * the user after the send operation completes. All data buffers given + * the user before the send operation completes. All data buffers given * to registered agents through this routine are owned by the receiving * client, except for snooping agents. Clients snooping MADs should not * modify the data referenced by @mad_recv_wc. @@ -485,17 +497,6 @@ int ib_unregister_mad_agent(struct ib_mad_agent *mad_agent); int ib_post_send_mad(struct ib_mad_send_buf *send_buf, struct ib_mad_send_buf **bad_send_buf); -/** - * ib_coalesce_recv_mad - Coalesces received MAD data into a single buffer. - * @mad_recv_wc: Work completion information for a received MAD. - * @buf: User-provided data buffer to receive the coalesced buffers. The - * referenced buffer should be at least the size of the mad_len specified - * by @mad_recv_wc. - * - * This call copies a chain of received MAD segments into a single data buffer, - * removing duplicated headers. - */ -void ib_coalesce_recv_mad(struct ib_mad_recv_wc *mad_recv_wc, void *buf); /** * ib_free_recv_mad - Returns data buffers used to receive a MAD. @@ -590,9 +591,10 @@ int ib_process_mad_wc(struct ib_mad_agent *mad_agent, * with an initialized work request structure. Users may modify the returned * MAD data buffer before posting the send. * - * The returned data buffer will be cleared. Users are responsible for - * initializing the common MAD and any class specific headers. If @rmpp_active - * is set, the RMPP header will be initialized for sending. + * The returned MAD header, class specific headers, and any padding will be + * cleared. Users are responsible for initializing the common MAD header, + * any class specific header, and MAD data area. + * If @rmpp_active is set, the RMPP header will be initialized for sending. */ struct ib_mad_send_buf * ib_create_send_mad(struct ib_mad_agent *mad_agent, u32 remote_qpn, u16 pkey_index, @@ -600,6 +602,16 @@ struct ib_mad_send_buf * ib_create_send_mad(struct ib_mad_agent *mad_agent, int hdr_len, int data_len, gfp_t gfp_mask); +/** + * ib_get_rmpp_segment - returns the data buffer for a given RMPP segment. + * @send_buf: Previously allocated send data buffer. + * @seg_num: number of segment to return + * + * This routine returns a pointer to the data buffer of an RMPP MAD. + * Users must provide synchronization to @send_buf around this call. + */ +void *ib_get_rmpp_segment(struct ib_mad_send_buf *send_buf, int seg_num); + /** * ib_free_send_mad - Returns data buffers used to send a MAD. * @send_buf: Previously allocated send data buffer. -- cgit v1.2.2 From 58383af629efb07e5a0694e445eda0c65b16e1de Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Mon, 6 Feb 2006 14:12:43 -0800 Subject: [PATCH] kobj_map semaphore to mutex conversion Convert the kobj_map code to use a mutex instead of a semaphore. It converts the single two users as well, genhd.c and char_dev.c. Signed-off-by: Jes Sorensen Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- include/linux/kobj_map.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/linux/kobj_map.h b/include/linux/kobj_map.h index cbe7d80080..bafe178a38 100644 --- a/include/linux/kobj_map.h +++ b/include/linux/kobj_map.h @@ -1,6 +1,6 @@ #ifdef __KERNEL__ -#include +#include typedef struct kobject *kobj_probe_t(dev_t, int *, void *); struct kobj_map; @@ -9,6 +9,6 @@ int kobj_map(struct kobj_map *, dev_t, unsigned long, struct module *, kobj_probe_t *, int (*)(dev_t, void *), void *); void kobj_unmap(struct kobj_map *, dev_t, unsigned long); struct kobject *kobj_lookup(struct kobj_map *, dev_t, int *); -struct kobj_map *kobj_map_init(kobj_probe_t *, struct semaphore *); +struct kobj_map *kobj_map_init(kobj_probe_t *, struct mutex *); #endif -- cgit v1.2.2 From 9f28bb7e1d0188a993403ab39b774785892805e1 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 20 Mar 2006 13:17:13 -0800 Subject: [PATCH] add EXPORT_SYMBOL_GPL_FUTURE() This patch adds the ability to mark symbols that will be changed in the future, so that kernel modules that don't include MODULE_LICENSE("GPL") and use the symbols, will be flagged and printed out to the system log. Signed-off-by: Greg Kroah-Hartman --- include/asm-generic/vmlinux.lds.h | 14 ++++++++++++++ include/linux/module.h | 9 +++++++++ 2 files changed, 23 insertions(+) (limited to 'include') diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index 35de20cf8f..9d11550b48 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -58,6 +58,13 @@ VMLINUX_SYMBOL(__stop___ksymtab_gpl) = .; \ } \ \ + /* Kernel symbol table: GPL-future-only symbols */ \ + __ksymtab_gpl_future : AT(ADDR(__ksymtab_gpl_future) - LOAD_OFFSET) { \ + VMLINUX_SYMBOL(__start___ksymtab_gpl_future) = .; \ + *(__ksymtab_gpl_future) \ + VMLINUX_SYMBOL(__stop___ksymtab_gpl_future) = .; \ + } \ + \ /* Kernel symbol table: Normal symbols */ \ __kcrctab : AT(ADDR(__kcrctab) - LOAD_OFFSET) { \ VMLINUX_SYMBOL(__start___kcrctab) = .; \ @@ -72,6 +79,13 @@ VMLINUX_SYMBOL(__stop___kcrctab_gpl) = .; \ } \ \ + /* Kernel symbol table: GPL-future-only symbols */ \ + __kcrctab_gpl_future : AT(ADDR(__kcrctab_gpl_future) - LOAD_OFFSET) { \ + VMLINUX_SYMBOL(__start___kcrctab_gpl_future) = .; \ + *(__kcrctab_gpl_future) \ + VMLINUX_SYMBOL(__stop___kcrctab_gpl_future) = .; \ + } \ + \ /* Kernel symbol table: strings */ \ __ksymtab_strings : AT(ADDR(__ksymtab_strings) - LOAD_OFFSET) { \ *(__ksymtab_strings) \ diff --git a/include/linux/module.h b/include/linux/module.h index 84d75f3a8a..a25d5f6154 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -198,6 +198,9 @@ void *__symbol_get_gpl(const char *symbol); #define EXPORT_SYMBOL_GPL(sym) \ __EXPORT_SYMBOL(sym, "_gpl") +#define EXPORT_SYMBOL_GPL_FUTURE(sym) \ + __EXPORT_SYMBOL(sym, "_gpl_future") + #endif struct module_ref @@ -255,6 +258,11 @@ struct module unsigned int num_gpl_syms; const unsigned long *gpl_crcs; + /* symbols that will be GPL-only in the near future. */ + const struct kernel_symbol *gpl_future_syms; + unsigned int num_gpl_future_syms; + const unsigned long *gpl_future_crcs; + /* Exception table */ unsigned int num_exentries; const struct exception_table_entry *extable; @@ -441,6 +449,7 @@ void module_remove_driver(struct device_driver *); #else /* !CONFIG_MODULES... */ #define EXPORT_SYMBOL(sym) #define EXPORT_SYMBOL_GPL(sym) +#define EXPORT_SYMBOL_GPL_FUTURE(sym) /* Given an address, look for it in the exception tables. */ static inline const struct exception_table_entry * -- cgit v1.2.2 From 03e88ae1b13dfdc8bbaa59b8198e1ca53aad12ac Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 16 Feb 2006 13:50:23 -0800 Subject: [PATCH] fix module sysfs files reference counting The module files, refcnt, version, and srcversion did not properly increment the owner's module reference count, allowing the modules to be removed while the files were open, causing oopses. This patch fixes this, and also fixes the problem that the version and srcversion files were not showing up, unless CONFIG_MODULE_UNLOAD was enabled, which is not correct. Cc: Nathan Lynch Signed-off-by: Greg Kroah-Hartman --- include/linux/module.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/module.h b/include/linux/module.h index a25d5f6154..70bd843c71 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -245,6 +245,7 @@ struct module /* Sysfs stuff. */ struct module_kobject mkobj; struct module_param_attrs *param_attrs; + struct module_attribute *modinfo_attrs; const char *version; const char *srcversion; -- cgit v1.2.2 From 4f2928d0a439553f0288d9483faf417430629635 Mon Sep 17 00:00:00 2001 From: Tilman Schmidt Date: Fri, 24 Feb 2006 11:05:45 +0100 Subject: [PATCH] Driver core: add macros notice(), dev_notice() Both usb.h and device.h have collections of convenience macros for printk() with the KERN_ERR, KERN_WARNING, and KERN_NOTICE severity levels. This patch adds macros for the KERN_NOTICE level which was so far uncatered for. These macros already exist privately in drivers/isdn/gigaset/gigaset.h (currently in the process of being submitted for the kernel tree) but they really belong with their brothers and sisters in include/linux/{device,usb}.h. Signed-off-by: Tilman Schmidt Signed-off-by: Greg Kroah-Hartman --- include/linux/device.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/linux/device.h b/include/linux/device.h index 58df18d9cd..5b595fdfb6 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -424,6 +424,8 @@ extern void firmware_unregister(struct subsystem *); dev_printk(KERN_INFO , dev , format , ## arg) #define dev_warn(dev, format, arg...) \ dev_printk(KERN_WARNING , dev , format , ## arg) +#define dev_notice(dev, format, arg...) \ + dev_printk(KERN_NOTICE , dev , format , ## arg) /* Create alias, so I can be autoloaded. */ #define MODULE_ALIAS_CHARDEV(major,minor) \ -- cgit v1.2.2 From 22f98c0cd7e003b896ee52ded945081307118745 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Sat, 4 Mar 2006 13:15:31 +0100 Subject: [PATCH] Kobject: kobject.h: fix a typo It shouldn't cause real harm, but it hurts my eyes. Signed-off-by: Adrian Bunk Signed-off-by: Greg Kroah-Hartman --- include/linux/kobject.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/kobject.h b/include/linux/kobject.h index c374b5fa8d..7ece63f8ab 100644 --- a/include/linux/kobject.h +++ b/include/linux/kobject.h @@ -255,7 +255,7 @@ struct subsys_attribute { extern int subsys_create_file(struct subsystem * , struct subsys_attribute *); extern void subsys_remove_file(struct subsystem * , struct subsys_attribute *); -#if defined(CONFIG_HOTPLUG) & defined(CONFIG_NET) +#if defined(CONFIG_HOTPLUG) && defined(CONFIG_NET) void kobject_uevent(struct kobject *kobj, enum kobject_action action); int add_uevent_var(char **envp, int num_envp, int *cur_index, -- cgit v1.2.2 From dd308bc355a1aa4f202fe9a3133b6c676cb9606c Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Tue, 7 Mar 2006 21:41:59 +1100 Subject: [PATCH] debugfs: Add debugfs_create_blob() helper for exporting binary data I wanted to export a binary blob via debugfs, and although it was pretty easy it seems like it'd be easier if there was a helper for it. It's a pity we need the wrapper struct but I can't see a cleaner way to do it. Signed-off-by: Michael Ellerman Signed-off-by: Greg Kroah-Hartman --- include/linux/debugfs.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'include') diff --git a/include/linux/debugfs.h b/include/linux/debugfs.h index a5fa6a6eed..4b0428e335 100644 --- a/include/linux/debugfs.h +++ b/include/linux/debugfs.h @@ -21,6 +21,11 @@ struct file_operations; +struct debugfs_blob_wrapper { + void *data; + unsigned long size; +}; + #if defined(CONFIG_DEBUG_FS) struct dentry *debugfs_create_file(const char *name, mode_t mode, struct dentry *parent, void *data, @@ -39,6 +44,9 @@ struct dentry *debugfs_create_u32(const char *name, mode_t mode, struct dentry *debugfs_create_bool(const char *name, mode_t mode, struct dentry *parent, u32 *value); +struct dentry *debugfs_create_blob(const char *name, mode_t mode, + struct dentry *parent, + struct debugfs_blob_wrapper *blob); #else #include @@ -94,6 +102,13 @@ static inline struct dentry *debugfs_create_bool(const char *name, mode_t mode, return ERR_PTR(-ENODEV); } +static inline struct dentry *debugfs_create_blob(const char *name, mode_t mode, + struct dentry *parent, + struct debugfs_blob_wrapper *blob) +{ + return ERR_PTR(-ENODEV); +} + #endif #endif -- cgit v1.2.2 From 7423172a50968de1905a61413c52bb070a62f5ce Mon Sep 17 00:00:00 2001 From: Jun'ichi Nomura Date: Mon, 13 Mar 2006 17:14:25 -0500 Subject: [PATCH] kobject_add_dir Adding kobject_add_dir() function which creates a subdirectory for a given kobject. Signed-off-by: Jun'ichi Nomura Signed-off-by: Greg Kroah-Hartman --- include/linux/kobject.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/linux/kobject.h b/include/linux/kobject.h index 7ece63f8ab..4cb1214ec2 100644 --- a/include/linux/kobject.h +++ b/include/linux/kobject.h @@ -80,6 +80,8 @@ extern void kobject_unregister(struct kobject *); extern struct kobject * kobject_get(struct kobject *); extern void kobject_put(struct kobject *); +extern struct kobject *kobject_add_dir(struct kobject *, const char *); + extern char * kobject_get_path(struct kobject *, gfp_t); struct kobj_type { -- cgit v1.2.2 From a29d642a4aa99c5234314ab2523281139226c231 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Tue, 7 Mar 2006 23:53:25 -0800 Subject: [PATCH] get_cpu_sysdev() signedness fix Doing (int < NR_CPUS) doesn't dtrt if it's negative.. Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- include/linux/cpu.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/cpu.h b/include/linux/cpu.h index 0ed1d4853c..d612b89dce 100644 --- a/include/linux/cpu.h +++ b/include/linux/cpu.h @@ -32,7 +32,7 @@ struct cpu { }; extern int register_cpu(struct cpu *, int, struct node *); -extern struct sys_device *get_cpu_sysdev(int cpu); +extern struct sys_device *get_cpu_sysdev(unsigned cpu); #ifdef CONFIG_HOTPLUG_CPU extern void unregister_cpu(struct cpu *, struct node *); #endif -- cgit v1.2.2 From e266a12492f7ca9142882710bff92e902b7c95c8 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Tue, 8 Nov 2005 21:05:43 +0100 Subject: [PATCH] USB: drivers/usb/core/message.c: make usb_get_string() static After the removal of usb-midi.c, there's no longer any external user of usb_get_string(). Signed-off-by: Adrian Bunk Signed-off-by: Greg Kroah-Hartman --- include/linux/usb.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include') diff --git a/include/linux/usb.h b/include/linux/usb.h index 827cc6de5f..130d125fda 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -1018,8 +1018,6 @@ extern int usb_get_descriptor(struct usb_device *dev, unsigned char desctype, unsigned char descindex, void *buf, int size); extern int usb_get_status(struct usb_device *dev, int type, int target, void *data); -extern int usb_get_string(struct usb_device *dev, - unsigned short langid, unsigned char index, void *buf, int size); extern int usb_string(struct usb_device *dev, int index, char *buf, size_t size); -- cgit v1.2.2 From 80cb9aee01245b38325dd84f1359b14a3f01f10d Mon Sep 17 00:00:00 2001 From: Randy Vinson Date: Fri, 20 Jan 2006 13:53:38 -0800 Subject: [PATCH] USB: EHCI for Freescale 83xx Adding a Host Mode USB driver for the Freescale 83xx. This driver supports both the Dual-Role (DR) controller and the Multi-Port-Host (MPH) controller present in the Freescale MPC8349. It has been tested with the MPC8349CDS reference system. This driver depends on platform support code for setting up the pins on the device package in a manner appropriate for the board in use. Note that this patch requires selecting the EHCI controller option under the USB Host menu. Signed-off-by: Randy Vinson Signed-off-by: Greg Kroah-Hartman --- include/linux/fsl_devices.h | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'include') diff --git a/include/linux/fsl_devices.h b/include/linux/fsl_devices.h index a9f1cfd096..a3a0e078f7 100644 --- a/include/linux/fsl_devices.h +++ b/include/linux/fsl_devices.h @@ -83,5 +83,32 @@ struct fsl_i2c_platform_data { #define FSL_I2C_DEV_SEPARATE_DFSRR 0x00000001 #define FSL_I2C_DEV_CLOCK_5200 0x00000002 + +enum fsl_usb2_operating_modes { + FSL_USB2_MPH_HOST, + FSL_USB2_DR_HOST, + FSL_USB2_DR_DEVICE, + FSL_USB2_DR_OTG, +}; + +enum fsl_usb2_phy_modes { + FSL_USB2_PHY_NONE, + FSL_USB2_PHY_ULPI, + FSL_USB2_PHY_UTMI, + FSL_USB2_PHY_UTMI_WIDE, + FSL_USB2_PHY_SERIAL, +}; + +struct fsl_usb2_platform_data { + /* board specific information */ + enum fsl_usb2_operating_modes operating_mode; + enum fsl_usb2_phy_modes phy_mode; + unsigned int port_enables; +}; + +/* Flags in fsl_usb2_mph_platform_data */ +#define FSL_USB2_PORT0_ENABLED 0x00000001 +#define FSL_USB2_PORT1_ENABLED 0x00000002 + #endif /* _FSL_DEVICE_H_ */ #endif /* __KERNEL__ */ -- cgit v1.2.2 From 76fa9a240de4294a097235c9ddd470c21eb3449e Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Fri, 20 Jan 2006 14:06:09 -0800 Subject: [PATCH] USB: EHCI for AU1200 ALCHEMY: Add EHCI support for AU1200 Updated by removing the OHCI support Signed-off-by: Jordan Crouse Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- include/asm-mips/mach-mips/cpu-feature-overrides.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include') diff --git a/include/asm-mips/mach-mips/cpu-feature-overrides.h b/include/asm-mips/mach-mips/cpu-feature-overrides.h index 9f92aed177..e06af6c86f 100644 --- a/include/asm-mips/mach-mips/cpu-feature-overrides.h +++ b/include/asm-mips/mach-mips/cpu-feature-overrides.h @@ -29,7 +29,11 @@ /* #define cpu_has_prefetch ? */ #define cpu_has_mcheck 1 /* #define cpu_has_ejtag ? */ +#ifdef CONFIG_CPU_HAS_LLSC #define cpu_has_llsc 1 +#else +#define cpu_has_llsc 0 +#endif /* #define cpu_has_vtag_icache ? */ /* #define cpu_has_dc_aliases ? */ /* #define cpu_has_ic_fills_f_dc ? */ -- cgit v1.2.2 From 329af28b141ab4ae847aff1362864c4cc332641f Mon Sep 17 00:00:00 2001 From: David Brownell Date: Sat, 18 Feb 2006 12:31:05 -0800 Subject: [PATCH] USB: gadget driver section fixups This adds __init section annotations to gadget driver bind() routines to remove calls from .text into .init sections (for endpoint autoconfig). Likewise it adds __exit section annotations to their unbind() routines. The specification of the gadget driver register/unregister functions is updated to explicitly allow use of those sections. Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- include/linux/usb_gadget.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/linux/usb_gadget.h b/include/linux/usb_gadget.h index ff81117eb7..1d78870ed8 100644 --- a/include/linux/usb_gadget.h +++ b/include/linux/usb_gadget.h @@ -801,7 +801,9 @@ struct usb_gadget_driver { * Call this in your gadget driver's module initialization function, * to tell the underlying usb controller driver about your driver. * The driver's bind() function will be called to bind it to a - * gadget. This function must be called in a context that can sleep. + * gadget before this registration call returns. It's expected that + * the bind() functions will be in init sections. + * This function must be called in a context that can sleep. */ int usb_gadget_register_driver (struct usb_gadget_driver *driver); @@ -814,7 +816,8 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver); * going away. If the controller is connected to a USB host, * it will first disconnect(). The driver is also requested * to unbind() and clean up any device state, before this procedure - * finally returns. + * finally returns. It's expected that the unbind() functions + * will in in exit sections, so may not be linked in some kernels. * This function must be called in a context that can sleep. */ int usb_gadget_unregister_driver (struct usb_gadget_driver *driver); -- cgit v1.2.2 From 955189efb44742890f33c91df478877af25246da Mon Sep 17 00:00:00 2001 From: YOSHIFUJI Hideaki Date: Mon, 20 Mar 2006 16:54:09 -0800 Subject: [IPV6]: ADDRCONF: Use our standard algorithm for randomized ifid. RFC 3041 describes an algorithm to generate random interface identifier. In RFC 3041bis, it is allowed to use different algorithm than one described in RFC 3041. So, let's use our standard pseudo random algorithm to simplify our implementation. Signed-off-by: YOSHIFUJI Hideaki Signed-off-by: David S. Miller --- include/net/if_inet6.h | 3 --- 1 file changed, 3 deletions(-) (limited to 'include') diff --git a/include/net/if_inet6.h b/include/net/if_inet6.h index eb8afe3499..e459e1a0ae 100644 --- a/include/net/if_inet6.h +++ b/include/net/if_inet6.h @@ -180,11 +180,8 @@ struct inet6_dev #ifdef CONFIG_IPV6_PRIVACY u8 rndid[8]; - u8 entropy[8]; struct timer_list regen_timer; struct inet6_ifaddr *tempaddr_list; - __u8 work_eui64[8]; - __u8 work_digest[16]; #endif struct neigh_parms *nd_parms; -- cgit v1.2.2 From 65f5c7c1143fb8eed5bc7e7d8c926346e00fe3c0 Mon Sep 17 00:00:00 2001 From: YOSHIFUJI Hideaki Date: Mon, 20 Mar 2006 16:55:08 -0800 Subject: [IPV6]: ROUTE: Add accept_ra_defrtr sysctl. This controls whether we accept default router information in RAs. Signed-off-by: YOSHIFUJI Hideaki Signed-off-by: David S. Miller --- include/linux/ipv6.h | 2 ++ include/linux/sysctl.h | 1 + 2 files changed, 3 insertions(+) (limited to 'include') diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h index 9c8f4c9ed4..c5131a0286 100644 --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h @@ -145,6 +145,7 @@ struct ipv6_devconf { __s32 max_desync_factor; #endif __s32 max_addresses; + __s32 accept_ra_defrtr; void *sysctl; }; @@ -167,6 +168,7 @@ enum { DEVCONF_MAX_DESYNC_FACTOR, DEVCONF_MAX_ADDRESSES, DEVCONF_FORCE_MLD_VERSION, + DEVCONF_ACCEPT_RA_DEFRTR, DEVCONF_MAX }; diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index bac61db264..0f494137d0 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -531,6 +531,7 @@ enum { NET_IPV6_MAX_DESYNC_FACTOR=15, NET_IPV6_MAX_ADDRESSES=16, NET_IPV6_FORCE_MLD_VERSION=17, + NET_IPV6_ACCEPT_RA_DEFRTR=18, __NET_IPV6_MAX }; -- cgit v1.2.2 From c4fd30eb18666972230689eb30e8f90844bce635 Mon Sep 17 00:00:00 2001 From: YOSHIFUJI Hideaki Date: Mon, 20 Mar 2006 16:55:26 -0800 Subject: [IPV6]: ADDRCONF: Add accept_ra_pinfo sysctl. This controls whether we accept Prefix Information in RAs. Signed-off-by: YOSHIFUJI Hideaki Signed-off-by: David S. Miller --- include/linux/ipv6.h | 2 ++ include/linux/sysctl.h | 1 + 2 files changed, 3 insertions(+) (limited to 'include') diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h index c5131a0286..2c3b799480 100644 --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h @@ -146,6 +146,7 @@ struct ipv6_devconf { #endif __s32 max_addresses; __s32 accept_ra_defrtr; + __s32 accept_ra_pinfo; void *sysctl; }; @@ -169,6 +170,7 @@ enum { DEVCONF_MAX_ADDRESSES, DEVCONF_FORCE_MLD_VERSION, DEVCONF_ACCEPT_RA_DEFRTR, + DEVCONF_ACCEPT_RA_PINFO, DEVCONF_MAX }; diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index 0f494137d0..09378ea505 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -532,6 +532,7 @@ enum { NET_IPV6_MAX_ADDRESSES=16, NET_IPV6_FORCE_MLD_VERSION=17, NET_IPV6_ACCEPT_RA_DEFRTR=18, + NET_IPV6_ACCEPT_RA_PINFO=19, __NET_IPV6_MAX }; -- cgit v1.2.2 From 554cfb7ee5d4f2d0edb280e66e4a2db1906a8300 Mon Sep 17 00:00:00 2001 From: YOSHIFUJI Hideaki Date: Mon, 20 Mar 2006 17:00:26 -0800 Subject: [IPV6]: ROUTE: Eliminate lock for default route pointer. And prepare for more advanced router selection. Signed-off-by: YOSHIFUJI Hideaki Signed-off-by: David S. Miller --- include/net/ip6_route.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include') diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h index 1f2e428ca3..01acca06d6 100644 --- a/include/net/ip6_route.h +++ b/include/net/ip6_route.h @@ -91,8 +91,6 @@ extern struct rt6_info * rt6_add_dflt_router(struct in6_addr *gwaddr, extern void rt6_purge_dflt_routers(void); -extern void rt6_reset_dflt_pointer(struct rt6_info *rt); - extern void rt6_redirect(struct in6_addr *dest, struct in6_addr *saddr, struct neighbour *neigh, -- cgit v1.2.2 From ebacaaa0fdf4402cdf4c8e569f54af36b6f0aa2d Mon Sep 17 00:00:00 2001 From: YOSHIFUJI Hideaki Date: Mon, 20 Mar 2006 17:04:53 -0800 Subject: [IPV6]: ROUTE: Add support for Router Preference (RFC4191). Signed-off-by: YOSHIFUJI Hideaki Signed-off-by: David S. Miller --- include/linux/icmpv6.h | 11 +++++++++-- include/linux/ipv6_route.h | 8 ++++++++ include/net/ip6_route.h | 3 ++- 3 files changed, 19 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/linux/icmpv6.h b/include/linux/icmpv6.h index 0cf6c8b12c..c771a7db98 100644 --- a/include/linux/icmpv6.h +++ b/include/linux/icmpv6.h @@ -40,14 +40,16 @@ struct icmp6hdr { struct icmpv6_nd_ra { __u8 hop_limit; #if defined(__LITTLE_ENDIAN_BITFIELD) - __u8 reserved:6, + __u8 reserved:4, + router_pref:2, other:1, managed:1; #elif defined(__BIG_ENDIAN_BITFIELD) __u8 managed:1, other:1, - reserved:6; + router_pref:2, + reserved:4; #else #error "Please fix " #endif @@ -70,8 +72,13 @@ struct icmp6hdr { #define icmp6_addrconf_managed icmp6_dataun.u_nd_ra.managed #define icmp6_addrconf_other icmp6_dataun.u_nd_ra.other #define icmp6_rt_lifetime icmp6_dataun.u_nd_ra.rt_lifetime +#define icmp6_router_pref icmp6_dataun.u_nd_ra.router_pref }; +#define ICMPV6_ROUTER_PREF_LOW 0x3 +#define ICMPV6_ROUTER_PREF_MEDIUM 0x0 +#define ICMPV6_ROUTER_PREF_HIGH 0x1 +#define ICMPV6_ROUTER_PREF_INVALID 0x2 #define ICMPV6_DEST_UNREACH 1 #define ICMPV6_PKT_TOOBIG 2 diff --git a/include/linux/ipv6_route.h b/include/linux/ipv6_route.h index d7c41d1d70..f4b085c916 100644 --- a/include/linux/ipv6_route.h +++ b/include/linux/ipv6_route.h @@ -27,8 +27,16 @@ #define RTF_FLOW 0x02000000 /* flow significant route */ #define RTF_POLICY 0x04000000 /* policy route */ +#define RTF_PREF(pref) ((pref) << 27) +#define RTF_PREF_MASK 0x18000000 + #define RTF_LOCAL 0x80000000 +#ifdef __KERNEL__ +#define IPV6_EXTRACT_PREF(flag) (((flag) & RTF_PREF_MASK) >> 27) +#define IPV6_DECODE_PREF(pref) ((pref) ^ 2) /* 1:low,2:med,3:high */ +#endif + struct in6_rtmsg { struct in6_addr rtmsg_dst; struct in6_addr rtmsg_src; diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h index 01acca06d6..50161322b8 100644 --- a/include/net/ip6_route.h +++ b/include/net/ip6_route.h @@ -87,7 +87,8 @@ extern struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev, extern struct rt6_info * rt6_get_dflt_router(struct in6_addr *addr, struct net_device *dev); extern struct rt6_info * rt6_add_dflt_router(struct in6_addr *gwaddr, - struct net_device *dev); + struct net_device *dev, + unsigned int pref); extern void rt6_purge_dflt_routers(void); -- cgit v1.2.2 From 930d6ff2e2a5f1538448d3b0b2652a8f0c0f6cba Mon Sep 17 00:00:00 2001 From: YOSHIFUJI Hideaki Date: Mon, 20 Mar 2006 17:05:30 -0800 Subject: [IPV6]: ROUTE: Add accept_ra_rtr_pref sysctl. Signed-off-by: YOSHIFUJI Hideaki Signed-off-by: David S. Miller --- include/linux/ipv6.h | 4 ++++ include/linux/sysctl.h | 1 + 2 files changed, 5 insertions(+) (limited to 'include') diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h index 2c3b799480..108b75dccd 100644 --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h @@ -147,6 +147,9 @@ struct ipv6_devconf { __s32 max_addresses; __s32 accept_ra_defrtr; __s32 accept_ra_pinfo; +#ifdef CONFIG_IPV6_ROUTER_PREF + __s32 accept_ra_rtr_pref; +#endif void *sysctl; }; @@ -171,6 +174,7 @@ enum { DEVCONF_FORCE_MLD_VERSION, DEVCONF_ACCEPT_RA_DEFRTR, DEVCONF_ACCEPT_RA_PINFO, + DEVCONF_ACCEPT_RA_RTR_PREF, DEVCONF_MAX }; diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index 09378ea505..236f537b38 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -533,6 +533,7 @@ enum { NET_IPV6_FORCE_MLD_VERSION=17, NET_IPV6_ACCEPT_RA_DEFRTR=18, NET_IPV6_ACCEPT_RA_PINFO=19, + NET_IPV6_ACCEPT_RA_RTR_PREF=20, __NET_IPV6_MAX }; -- cgit v1.2.2 From 52e1635631b342803aecaf81a362c1464e3da2e5 Mon Sep 17 00:00:00 2001 From: YOSHIFUJI Hideaki Date: Mon, 20 Mar 2006 17:05:47 -0800 Subject: [IPV6]: ROUTE: Add router_probe_interval sysctl. Signed-off-by: YOSHIFUJI Hideaki Signed-off-by: David S. Miller --- include/linux/ipv6.h | 2 ++ include/linux/sysctl.h | 1 + 2 files changed, 3 insertions(+) (limited to 'include') diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h index 108b75dccd..c609cc7023 100644 --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h @@ -149,6 +149,7 @@ struct ipv6_devconf { __s32 accept_ra_pinfo; #ifdef CONFIG_IPV6_ROUTER_PREF __s32 accept_ra_rtr_pref; + __s32 rtr_probe_interval; #endif void *sysctl; }; @@ -175,6 +176,7 @@ enum { DEVCONF_ACCEPT_RA_DEFRTR, DEVCONF_ACCEPT_RA_PINFO, DEVCONF_ACCEPT_RA_RTR_PREF, + DEVCONF_RTR_PROBE_INTERVAL, DEVCONF_MAX }; diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index 236f537b38..f49488ffef 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -534,6 +534,7 @@ enum { NET_IPV6_ACCEPT_RA_DEFRTR=18, NET_IPV6_ACCEPT_RA_PINFO=19, NET_IPV6_ACCEPT_RA_RTR_PREF=20, + NET_IPV6_RTR_PROBE_INTERVAL=21, __NET_IPV6_MAX }; -- cgit v1.2.2 From 70ceb4f53929f73746be72f73707cd9f8753e2fc Mon Sep 17 00:00:00 2001 From: YOSHIFUJI Hideaki Date: Mon, 20 Mar 2006 17:06:24 -0800 Subject: [IPV6]: ROUTE: Add experimental support for Route Information Option in RA (RFC4191). Signed-off-by: YOSHIFUJI Hideaki Signed-off-by: David S. Miller --- include/linux/ipv6_route.h | 2 ++ include/net/ip6_route.h | 21 +++++++++++++++++++++ include/net/ndisc.h | 2 ++ 3 files changed, 25 insertions(+) (limited to 'include') diff --git a/include/linux/ipv6_route.h b/include/linux/ipv6_route.h index f4b085c916..b323ff5779 100644 --- a/include/linux/ipv6_route.h +++ b/include/linux/ipv6_route.h @@ -23,6 +23,8 @@ #define RTF_NONEXTHOP 0x00200000 /* route with no nexthop */ #define RTF_EXPIRES 0x00400000 +#define RTF_ROUTEINFO 0x00800000 /* route information - RA */ + #define RTF_CACHE 0x01000000 /* cache entry */ #define RTF_FLOW 0x02000000 /* flow significant route */ #define RTF_POLICY 0x04000000 /* policy route */ diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h index 50161322b8..a398ae5e30 100644 --- a/include/net/ip6_route.h +++ b/include/net/ip6_route.h @@ -7,6 +7,23 @@ #define IP6_RT_PRIO_KERN 512 #define IP6_RT_FLOW_MASK 0x00ff +struct route_info { + __u8 type; + __u8 length; + __u8 prefix_len; +#if defined(__BIG_ENDIAN_BITFIELD) + __u8 reserved_h:3, + route_pref:2, + reserved_l:3; +#elif defined(__LITTLE_ENDIAN_BITFIELD) + __u8 reserved_l:3, + route_pref:2, + reserved_h:3; +#endif + __u32 lifetime; + __u8 prefix[0]; /* 0,8 or 16 */ +}; + #ifdef __KERNEL__ #include @@ -92,6 +109,10 @@ extern struct rt6_info * rt6_add_dflt_router(struct in6_addr *gwaddr, extern void rt6_purge_dflt_routers(void); +extern int rt6_route_rcv(struct net_device *dev, + u8 *opt, int len, + struct in6_addr *gwaddr); + extern void rt6_redirect(struct in6_addr *dest, struct in6_addr *saddr, struct neighbour *neigh, diff --git a/include/net/ndisc.h b/include/net/ndisc.h index bbac87eeb4..91fa271a00 100644 --- a/include/net/ndisc.h +++ b/include/net/ndisc.h @@ -22,6 +22,8 @@ enum { ND_OPT_PREFIX_INFO = 3, /* RFC2461 */ ND_OPT_REDIRECT_HDR = 4, /* RFC2461 */ ND_OPT_MTU = 5, /* RFC2461 */ + __ND_OPT_ARRAY_MAX, + ND_OPT_ROUTE_INFO = 24, /* RFC4191 */ __ND_OPT_MAX }; -- cgit v1.2.2 From 09c884d4c3b45cda904c2291d4723074ff523611 Mon Sep 17 00:00:00 2001 From: YOSHIFUJI Hideaki Date: Mon, 20 Mar 2006 17:07:03 -0800 Subject: [IPV6]: ROUTE: Add accept_ra_rt_info_max_plen sysctl. Signed-off-by: YOSHIFUJI Hideaki Signed-off-by: David S. Miller --- include/linux/ipv6.h | 4 ++++ include/linux/sysctl.h | 1 + 2 files changed, 5 insertions(+) (limited to 'include') diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h index c609cc7023..1263d8cb3c 100644 --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h @@ -150,6 +150,9 @@ struct ipv6_devconf { #ifdef CONFIG_IPV6_ROUTER_PREF __s32 accept_ra_rtr_pref; __s32 rtr_probe_interval; +#ifdef CONFIG_IPV6_ROUTE_INFO + __s32 accept_ra_rt_info_max_plen; +#endif #endif void *sysctl; }; @@ -177,6 +180,7 @@ enum { DEVCONF_ACCEPT_RA_PINFO, DEVCONF_ACCEPT_RA_RTR_PREF, DEVCONF_RTR_PROBE_INTERVAL, + DEVCONF_ACCEPT_RA_RT_INFO_MAX_PLEN, DEVCONF_MAX }; diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index f49488ffef..8ad4beab28 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -535,6 +535,7 @@ enum { NET_IPV6_ACCEPT_RA_PINFO=19, NET_IPV6_ACCEPT_RA_RTR_PREF=20, NET_IPV6_RTR_PROBE_INTERVAL=21, + NET_IPV6_ACCEPT_RA_RT_INFO_MAX_PLEN=22, __NET_IPV6_MAX }; -- cgit v1.2.2 From b00055aacdb172c05067612278ba27265fcd05ce Mon Sep 17 00:00:00 2001 From: Stefan Rompf Date: Mon, 20 Mar 2006 17:09:11 -0800 Subject: [NET] core: add RFC2863 operstate this patch adds a dormant flag to network devices, RFC2863 operstate derived from these flags and possibility for userspace interaction. It allows drivers to signal that a device is unusable for user traffic without disabling queueing (and therefore the possibility for protocol establishment traffic to flow) and a userspace supplicant (WPA, 802.1X) to mark a device unusable without changes to the driver. It is the result of our long discussion. However I must admit that it represents what Jamal and I agreed on with compromises towards Krzysztof, but Thomas and Krzysztof still disagree with some parts. Anyway I think it should be applied. Signed-off-by: Stefan Rompf Signed-off-by: David S. Miller --- include/linux/if.h | 26 +++++++++++++++++++++++--- include/linux/netdevice.h | 35 +++++++++++++++++++++++++++++++++-- include/linux/rtnetlink.h | 2 ++ 3 files changed, 58 insertions(+), 5 deletions(-) (limited to 'include') diff --git a/include/linux/if.h b/include/linux/if.h index 12c6f6d157..374e20ad8b 100644 --- a/include/linux/if.h +++ b/include/linux/if.h @@ -33,7 +33,7 @@ #define IFF_LOOPBACK 0x8 /* is a loopback net */ #define IFF_POINTOPOINT 0x10 /* interface is has p-p link */ #define IFF_NOTRAILERS 0x20 /* avoid use of trailers */ -#define IFF_RUNNING 0x40 /* interface running and carrier ok */ +#define IFF_RUNNING 0x40 /* interface RFC2863 OPER_UP */ #define IFF_NOARP 0x80 /* no ARP protocol */ #define IFF_PROMISC 0x100 /* receive all packets */ #define IFF_ALLMULTI 0x200 /* receive all multicast packets*/ @@ -43,12 +43,16 @@ #define IFF_MULTICAST 0x1000 /* Supports multicast */ -#define IFF_VOLATILE (IFF_LOOPBACK|IFF_POINTOPOINT|IFF_BROADCAST|IFF_MASTER|IFF_SLAVE|IFF_RUNNING) - #define IFF_PORTSEL 0x2000 /* can set media type */ #define IFF_AUTOMEDIA 0x4000 /* auto media select active */ #define IFF_DYNAMIC 0x8000 /* dialup device with changing addresses*/ +#define IFF_LOWER_UP 0x10000 /* driver signals L1 up */ +#define IFF_DORMANT 0x20000 /* driver signals dormant */ + +#define IFF_VOLATILE (IFF_LOOPBACK|IFF_POINTOPOINT|IFF_BROADCAST|\ + IFF_MASTER|IFF_SLAVE|IFF_RUNNING|IFF_LOWER_UP|IFF_DORMANT) + /* Private (from user) interface flags (netdevice->priv_flags). */ #define IFF_802_1Q_VLAN 0x1 /* 802.1Q VLAN device. */ #define IFF_EBRIDGE 0x2 /* Ethernet bridging device. */ @@ -83,6 +87,22 @@ #define IF_PROTO_FR_ETH_PVC 0x200B #define IF_PROTO_RAW 0x200C /* RAW Socket */ +/* RFC 2863 operational status */ +enum { + IF_OPER_UNKNOWN, + IF_OPER_NOTPRESENT, + IF_OPER_DOWN, + IF_OPER_LOWERLAYERDOWN, + IF_OPER_TESTING, + IF_OPER_DORMANT, + IF_OPER_UP, +}; + +/* link modes */ +enum { + IF_LINK_MODE_DEFAULT, + IF_LINK_MODE_DORMANT, /* limit upward transition to dormant */ +}; /* * Device mapping structure. I'd just gone off and designed a diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 7fda03d338..b825be201b 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -230,7 +230,8 @@ enum netdev_state_t __LINK_STATE_SCHED, __LINK_STATE_NOCARRIER, __LINK_STATE_RX_SCHED, - __LINK_STATE_LINKWATCH_PENDING + __LINK_STATE_LINKWATCH_PENDING, + __LINK_STATE_DORMANT, }; @@ -335,11 +336,14 @@ struct net_device */ - unsigned short flags; /* interface flags (a la BSD) */ + unsigned int flags; /* interface flags (a la BSD) */ unsigned short gflags; unsigned short priv_flags; /* Like 'flags' but invisible to userspace. */ unsigned short padded; /* How much padding added by alloc_netdev() */ + unsigned char operstate; /* RFC2863 operstate */ + unsigned char link_mode; /* mapping policy to operstate */ + unsigned mtu; /* interface MTU value */ unsigned short type; /* interface hardware type */ unsigned short hard_header_len; /* hardware hdr length */ @@ -714,6 +718,10 @@ static inline void dev_put(struct net_device *dev) /* Carrier loss detection, dial on demand. The functions netif_carrier_on * and _off may be called from IRQ context, but it is caller * who is responsible for serialization of these calls. + * + * The name carrier is inappropriate, these functions should really be + * called netif_lowerlayer_*() because they represent the state of any + * kind of lower layer not just hardware media. */ extern void linkwatch_fire_event(struct net_device *dev); @@ -729,6 +737,29 @@ extern void netif_carrier_on(struct net_device *dev); extern void netif_carrier_off(struct net_device *dev); +static inline void netif_dormant_on(struct net_device *dev) +{ + if (!test_and_set_bit(__LINK_STATE_DORMANT, &dev->state)) + linkwatch_fire_event(dev); +} + +static inline void netif_dormant_off(struct net_device *dev) +{ + if (test_and_clear_bit(__LINK_STATE_DORMANT, &dev->state)) + linkwatch_fire_event(dev); +} + +static inline int netif_dormant(const struct net_device *dev) +{ + return test_bit(__LINK_STATE_DORMANT, &dev->state); +} + + +static inline int netif_oper_up(const struct net_device *dev) { + return (dev->operstate == IF_OPER_UP || + dev->operstate == IF_OPER_UNKNOWN /* backward compat */); +} + /* Hot-plugging. */ static inline int netif_device_present(struct net_device *dev) { diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h index d50482ba27..edccefb451 100644 --- a/include/linux/rtnetlink.h +++ b/include/linux/rtnetlink.h @@ -733,6 +733,8 @@ enum #define IFLA_MAP IFLA_MAP IFLA_WEIGHT, #define IFLA_WEIGHT IFLA_WEIGHT + IFLA_OPERSTATE, + IFLA_LINKMODE, __IFLA_MAX }; -- cgit v1.2.2 From 77d2ca350018c507815f5d38a40ffb597eb9ae25 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Mon, 20 Mar 2006 17:12:12 -0800 Subject: [NET]: Reduce size of struct sk_buff on 64 bit architectures Move skb->nf_mark next to skb->tc_index to remove a 4 byte hole between skb->nfmark and skb->nfct and another one between skb->users and skb->head when CONFIG_NETFILTER, CONFIG_NET_SCHED and CONFIG_NET_CLS_ACT are enabled. For all other combinations the size stays the same. Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- include/linux/skbuff.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index ad7cc22bd4..838ce0fdce 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -270,7 +270,6 @@ struct sk_buff { void (*destructor)(struct sk_buff *skb); #ifdef CONFIG_NETFILTER - __u32 nfmark; struct nf_conntrack *nfct; #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) struct sk_buff *nfct_reasm; @@ -278,6 +277,7 @@ struct sk_buff { #ifdef CONFIG_BRIDGE_NETFILTER struct nf_bridge_info *nf_bridge; #endif + __u32 nfmark; #endif /* CONFIG_NETFILTER */ #ifdef CONFIG_NET_SCHED __u16 tc_index; /* traffic control index */ -- cgit v1.2.2 From 5ee956125a780baf15f2c1d09f2cbf8adcf598fe Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Mon, 20 Mar 2006 17:14:12 -0800 Subject: [NETFILTER] NAT sequence adjustment: Save eight bytes per conntrack This patch reduces the size of 'struct ip_conntrack' on systems with NAT by eight bytes. The sequence number delta values can be int16_t, since we only support one sequence number modification per window anyway, and one such modification is not going to exceed 32kB ;) Signed-off-by: Harald Welte Signed-off-by: David S. Miller --- include/linux/netfilter_ipv4/ip_nat.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/netfilter_ipv4/ip_nat.h b/include/linux/netfilter_ipv4/ip_nat.h index 41a107de17..e9f5ed1d9f 100644 --- a/include/linux/netfilter_ipv4/ip_nat.h +++ b/include/linux/netfilter_ipv4/ip_nat.h @@ -23,7 +23,7 @@ struct ip_nat_seq { * modification (if any) */ u_int32_t correction_pos; /* sequence number offset before and after last modification */ - int32_t offset_before, offset_after; + int16_t offset_before, offset_after; }; /* Single range specification. */ -- cgit v1.2.2 From 0af5f6c1eba4a18e6b2ed518b589927d778c6c16 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Mon, 20 Mar 2006 17:15:11 -0800 Subject: [NETFILTER] nfnetlink_log: add sequence numbers for log events By using a sequence number for every logged netfilter event, we can determine from userspace whether logging information was lots somewhere downstream. The user has a choice of either having per-instance local sequence counters, or using a global sequence counter, or both. Signed-off-by: Harald Welte Signed-off-by: David S. Miller --- include/linux/netfilter/nfnetlink_log.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'include') diff --git a/include/linux/netfilter/nfnetlink_log.h b/include/linux/netfilter/nfnetlink_log.h index b04b038805..a7497c7436 100644 --- a/include/linux/netfilter/nfnetlink_log.h +++ b/include/linux/netfilter/nfnetlink_log.h @@ -47,6 +47,8 @@ enum nfulnl_attr_type { NFULA_PAYLOAD, /* opaque data payload */ NFULA_PREFIX, /* string prefix */ NFULA_UID, /* user id of socket */ + NFULA_SEQ, /* instance-local sequence number */ + NFULA_SEQ_GLOBAL, /* global sequence number */ __NFULA_MAX }; @@ -77,6 +79,7 @@ enum nfulnl_attr_config { NFULA_CFG_NLBUFSIZ, /* u_int32_t buffer size */ NFULA_CFG_TIMEOUT, /* u_int32_t in 1/100 s */ NFULA_CFG_QTHRESH, /* u_int32_t */ + NFULA_CFG_FLAGS, /* u_int16_t */ __NFULA_CFG_MAX }; #define NFULA_CFG_MAX (__NFULA_CFG_MAX -1) @@ -85,4 +88,7 @@ enum nfulnl_attr_config { #define NFULNL_COPY_META 0x01 #define NFULNL_COPY_PACKET 0x02 +#define NFULNL_CFG_F_SEQ 0x0001 +#define NFULNL_CFG_F_SEQ_GLOBAL 0x0002 + #endif /* _NFNETLINK_LOG_H */ -- cgit v1.2.2 From d8dcffee860d6b63996923b10f07c91d3d6c2fab Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 20 Mar 2006 17:18:05 -0800 Subject: [LIST]: Introduce list_for_each_entry_safe_from For iterate over list of given type from existing point safe against removal of list entry. Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: David S. Miller --- include/linux/list.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'include') diff --git a/include/linux/list.h b/include/linux/list.h index 47208bd99f..beb6e48e11 100644 --- a/include/linux/list.h +++ b/include/linux/list.h @@ -437,6 +437,19 @@ static inline void list_splice_init(struct list_head *list, &pos->member != (head); \ pos = n, n = list_entry(n->member.next, typeof(*n), member)) +/** + * list_for_each_entry_safe_from - iterate over list of given type + * from existing point safe against removal of list entry + * @pos: the type * to use as a loop counter. + * @n: another type * to use as temporary storage + * @head: the head for your list. + * @member: the name of the list_struct within the struct. + */ +#define list_for_each_entry_safe_from(pos, n, head, member) \ + for (n = list_entry(pos->member.next, typeof(*pos), member); \ + &pos->member != (head); \ + pos = n, n = list_entry(n->member.next, typeof(*n), member)) + /** * list_for_each_entry_safe_reverse - iterate backwards over list of given type safe against * removal of list entry -- cgit v1.2.2 From e229c2fb3370a0c4ebac06cad67ce1cb35abcfe6 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 20 Mar 2006 17:19:17 -0800 Subject: [LIST]: Introduce list_for_each_entry_from For iterating over list of given type continuing from existing point. Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: David S. Miller --- include/linux/list.h | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'include') diff --git a/include/linux/list.h b/include/linux/list.h index beb6e48e11..67258b47e9 100644 --- a/include/linux/list.h +++ b/include/linux/list.h @@ -410,6 +410,17 @@ static inline void list_splice_init(struct list_head *list, prefetch(pos->member.next), &pos->member != (head); \ pos = list_entry(pos->member.next, typeof(*pos), member)) +/** + * list_for_each_entry_from - iterate over list of given type + * continuing from existing point + * @pos: the type * to use as a loop counter. + * @head: the head for your list. + * @member: the name of the list_struct within the struct. + */ +#define list_for_each_entry_from(pos, head, member) \ + for (; prefetch(pos->member.next), &pos->member != (head); \ + pos = list_entry(pos->member.next, typeof(*pos), member)) + /** * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry * @pos: the type * to use as a loop counter. -- cgit v1.2.2 From 2a91aa3967398fb94eccc8da67c82bce9f67afdf Mon Sep 17 00:00:00 2001 From: Andrea Bittau Date: Mon, 20 Mar 2006 17:41:47 -0800 Subject: [DCCP] CCID2: Initial CCID2 (TCP-Like) implementation Original work by Andrea Bittau, Arnaldo Melo cleaned up and fixed several issues on the merge process. For now CCID2 was turned the default for all SOCK_DCCP connections, but this will be remedied soon with the merge of the feature negotiation code. Signed-off-by: Andrea Bittau Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: David S. Miller --- include/linux/dccp.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/linux/dccp.h b/include/linux/dccp.h index 088529f549..268b4579d7 100644 --- a/include/linux/dccp.h +++ b/include/linux/dccp.h @@ -314,9 +314,9 @@ static inline unsigned int dccp_hdr_len(const struct sk_buff *skb) /* initial values for each feature */ #define DCCPF_INITIAL_SEQUENCE_WINDOW 100 -/* FIXME: for now we're using CCID 3 (TFRC) */ -#define DCCPF_INITIAL_CCID 3 -#define DCCPF_INITIAL_SEND_ACK_VECTOR 0 +/* FIXME: for now we're using CCID 2 (TCP-Like) */ +#define DCCPF_INITIAL_CCID 2 +#define DCCPF_INITIAL_SEND_ACK_VECTOR 1 /* FIXME: for now we're default to 1 but it should really be 0 */ #define DCCPF_INITIAL_SEND_NDP_COUNT 1 @@ -430,6 +430,8 @@ struct dccp_sock { struct timeval dccps_timestamp_time; __u32 dccps_timestamp_echo; __u32 dccps_packet_size; + __u16 dccps_l_ack_ratio; + __u16 dccps_r_ack_ratio; unsigned long dccps_ndp_count; __u32 dccps_mss_cache; struct dccp_options dccps_options; -- cgit v1.2.2 From afe00251dd9b53d51de91ff0099961f42bbf3754 Mon Sep 17 00:00:00 2001 From: Andrea Bittau Date: Mon, 20 Mar 2006 17:43:56 -0800 Subject: [DCCP]: Initial feature negotiation implementation Still needs more work, but boots and doesn't crashes, even does some negotiation! 18:38:52.174934 127.0.0.1.43458 > 127.0.0.1.5001: request 18:38:52.218526 127.0.0.1.5001 > 127.0.0.1.43458: response 18:38:52.185398 127.0.0.1.43458 > 127.0.0.1.5001: :-) Signed-off-by: Andrea Bittau Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: David S. Miller --- include/linux/dccp.h | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/dccp.h b/include/linux/dccp.h index 268b4579d7..f91c8a6240 100644 --- a/include/linux/dccp.h +++ b/include/linux/dccp.h @@ -154,6 +154,10 @@ enum { DCCPO_MANDATORY = 1, DCCPO_MIN_RESERVED = 3, DCCPO_MAX_RESERVED = 31, + DCCPO_CHANGE_L = 32, + DCCPO_CONFIRM_L = 33, + DCCPO_CHANGE_R = 34, + DCCPO_CONFIRM_R = 35, DCCPO_NDP_COUNT = 37, DCCPO_ACK_VECTOR_0 = 38, DCCPO_ACK_VECTOR_1 = 39, @@ -168,7 +172,9 @@ enum { /* DCCP features */ enum { DCCPF_RESERVED = 0, + DCCPF_CCID = 1, DCCPF_SEQUENCE_WINDOW = 3, + DCCPF_ACK_RATIO = 5, DCCPF_SEND_ACK_VECTOR = 6, DCCPF_SEND_NDP_COUNT = 7, /* 10-127 reserved */ @@ -176,9 +182,18 @@ enum { DCCPF_MAX_CCID_SPECIFIC = 255, }; +/* this structure is argument to DCCP_SOCKOPT_CHANGE_X */ +struct dccp_so_feat { + __u8 dccpsf_feat; + __u8 *dccpsf_val; + __u8 dccpsf_len; +}; + /* DCCP socket options */ #define DCCP_SOCKOPT_PACKET_SIZE 1 #define DCCP_SOCKOPT_SERVICE 2 +#define DCCP_SOCKOPT_CHANGE_L 3 +#define DCCP_SOCKOPT_CHANGE_R 4 #define DCCP_SOCKOPT_CCID_RX_INFO 128 #define DCCP_SOCKOPT_CCID_TX_INFO 192 @@ -314,8 +329,8 @@ static inline unsigned int dccp_hdr_len(const struct sk_buff *skb) /* initial values for each feature */ #define DCCPF_INITIAL_SEQUENCE_WINDOW 100 -/* FIXME: for now we're using CCID 2 (TCP-Like) */ #define DCCPF_INITIAL_CCID 2 +#define DCCPF_INITIAL_ACK_RATIO 2 #define DCCPF_INITIAL_SEND_ACK_VECTOR 1 /* FIXME: for now we're default to 1 but it should really be 0 */ #define DCCPF_INITIAL_SEND_NDP_COUNT 1 @@ -335,6 +350,24 @@ struct dccp_options { __u8 dccpo_tx_ccid; __u8 dccpo_send_ack_vector; __u8 dccpo_send_ndp_count; + __u8 dccpo_ack_ratio; + struct list_head dccpo_pending; + struct list_head dccpo_conf; +}; + +struct dccp_opt_conf { + __u8 *dccpoc_val; + __u8 dccpoc_len; +}; + +struct dccp_opt_pend { + struct list_head dccpop_node; + __u8 dccpop_type; + __u8 dccpop_feat; + __u8 *dccpop_val; + __u8 dccpop_len; + int dccpop_conf; + struct dccp_opt_conf *dccpop_sc; }; extern void __dccp_options_init(struct dccp_options *dccpo); -- cgit v1.2.2 From d4d2c558fd3e1f5e386b153f194aa8f0be496c77 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Mon, 20 Mar 2006 17:47:20 -0800 Subject: [TG3]: Add support for 5714S and 5715S Add support for 5714S and 5715S. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- include/linux/pci_ids.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 751eea58bd..a3a09cceb0 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -1857,12 +1857,14 @@ #define PCI_DEVICE_ID_TIGON3_5705M 0x165d #define PCI_DEVICE_ID_TIGON3_5705M_2 0x165e #define PCI_DEVICE_ID_TIGON3_5714 0x1668 +#define PCI_DEVICE_ID_TIGON3_5714S 0x1669 #define PCI_DEVICE_ID_TIGON3_5780 0x166a #define PCI_DEVICE_ID_TIGON3_5780S 0x166b #define PCI_DEVICE_ID_TIGON3_5705F 0x166e #define PCI_DEVICE_ID_TIGON3_5750 0x1676 #define PCI_DEVICE_ID_TIGON3_5751 0x1677 #define PCI_DEVICE_ID_TIGON3_5715 0x1678 +#define PCI_DEVICE_ID_TIGON3_5715S 0x1679 #define PCI_DEVICE_ID_TIGON3_5750M 0x167c #define PCI_DEVICE_ID_TIGON3_5751M 0x167d #define PCI_DEVICE_ID_TIGON3_5751F 0x167e -- cgit v1.2.2 From 5d424d5a674f782d0659a3b66d951f412901faee Mon Sep 17 00:00:00 2001 From: John Heffner Date: Mon, 20 Mar 2006 17:53:41 -0800 Subject: [TCP]: MTU probing Implementation of packetization layer path mtu discovery for TCP, based on the internet-draft currently found at . Signed-off-by: John Heffner Signed-off-by: David S. Miller --- include/linux/sysctl.h | 2 ++ include/net/inet_connection_sock.h | 13 +++++++++++++ include/net/tcp.h | 9 +++++++++ 3 files changed, 24 insertions(+) (limited to 'include') diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index 8ad4beab28..6e8880ea49 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -397,6 +397,8 @@ enum NET_TCP_CONG_CONTROL=110, NET_TCP_ABC=111, NET_IPV4_IPFRAG_MAX_DIST=112, + NET_TCP_MTU_PROBING=113, + NET_TCP_BASE_MSS=114, }; enum { diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h index fa587c94e9..b3abe33f4e 100644 --- a/include/net/inet_connection_sock.h +++ b/include/net/inet_connection_sock.h @@ -72,6 +72,7 @@ struct inet_connection_sock_af_ops { * @icsk_probes_out: unanswered 0 window probes * @icsk_ext_hdr_len: Network protocol overhead (IP/IPv6 options) * @icsk_ack: Delayed ACK control data + * @icsk_mtup; MTU probing control data */ struct inet_connection_sock { /* inet_sock has to be the first member! */ @@ -104,6 +105,18 @@ struct inet_connection_sock { __u16 last_seg_size; /* Size of last incoming segment */ __u16 rcv_mss; /* MSS used for delayed ACK decisions */ } icsk_ack; + struct { + int enabled; + + /* Range of MTUs to search */ + int search_high; + int search_low; + + /* Information on the current probe. */ + int probe_size; + __u32 probe_seq_start; + __u32 probe_seq_end; + } icsk_mtup; u32 icsk_ca_priv[16]; #define ICSK_CA_PRIV_SIZE (16 * sizeof(u32)) }; diff --git a/include/net/tcp.h b/include/net/tcp.h index 77f21c65bb..16879fa560 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -60,6 +60,9 @@ extern void tcp_time_wait(struct sock *sk, int state, int timeo); /* Minimal RCV_MSS. */ #define TCP_MIN_RCVMSS 536U +/* The least MTU to use for probing */ +#define TCP_BASE_MSS 512 + /* After receiving this amount of duplicate ACKs fast retransmit starts. */ #define TCP_FASTRETRANS_THRESH 3 @@ -219,6 +222,8 @@ extern int sysctl_tcp_nometrics_save; extern int sysctl_tcp_moderate_rcvbuf; extern int sysctl_tcp_tso_win_divisor; extern int sysctl_tcp_abc; +extern int sysctl_tcp_mtu_probing; +extern int sysctl_tcp_base_mss; extern atomic_t tcp_memory_allocated; extern atomic_t tcp_sockets_allocated; @@ -447,6 +452,10 @@ extern int tcp_read_sock(struct sock *sk, read_descriptor_t *desc, extern void tcp_initialize_rcv_mss(struct sock *sk); +extern int tcp_mtu_to_mss(struct sock *sk, int pmtu); +extern int tcp_mss_to_mtu(struct sock *sk, int mss); +extern void tcp_mtup_init(struct sock *sk); + static inline void __tcp_fast_path_on(struct tcp_sock *tp, u32 snd_wnd) { tp->pred_flags = htonl((tp->tcp_header_len << 26) | -- cgit v1.2.2 From dc808fe28db59fadf4ec32d53f62477fa28f3be8 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Mon, 20 Mar 2006 17:56:32 -0800 Subject: [NETFILTER] nf_conntrack: clean up to reduce size of 'struct nf_conn' This patch moves all helper related data fields of 'struct nf_conn' into a separate structure 'struct nf_conn_help'. This new structure is only present in conntrack entries for which we actually have a helper loaded. Also, this patch cleans up the nf_conntrack 'features' mechanism to resemble what the original idea was: Just glue the feature-specific data structures at the end of 'struct nf_conn', and explicitly re-calculate the pointer to it when needed rather than keeping pointers around. Saves 20 bytes per conntrack on my x86_64 box. A non-helped conntrack is 276 bytes. We still need to save another 20 bytes in order to fit into to target of 256bytes. Signed-off-by: Harald Welte Signed-off-by: David S. Miller --- include/net/netfilter/nf_conntrack.h | 56 ++++++++++++++++++++++-------------- 1 file changed, 34 insertions(+), 22 deletions(-) (limited to 'include') diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h index 6d075ca16e..2743c156ca 100644 --- a/include/net/netfilter/nf_conntrack.h +++ b/include/net/netfilter/nf_conntrack.h @@ -67,6 +67,18 @@ do { \ struct nf_conntrack_helper; +/* nf_conn feature for connections that have a helper */ +struct nf_conn_help { + /* Helper. if any */ + struct nf_conntrack_helper *helper; + + union nf_conntrack_help help; + + /* Current number of expected connections */ + unsigned int expecting; +}; + + #include struct nf_conn { @@ -81,6 +93,9 @@ struct nf_conn /* Have we seen traffic both ways yet? (bitset) */ unsigned long status; + /* If we were expected by an expectation, this will be it */ + struct nf_conn *master; + /* Timer function; drops refcnt when it goes off. */ struct timer_list timeout; @@ -88,38 +103,22 @@ struct nf_conn /* Accounting Information (same cache line as other written members) */ struct ip_conntrack_counter counters[IP_CT_DIR_MAX]; #endif - /* If we were expected by an expectation, this will be it */ - struct nf_conn *master; - - /* Current number of expected connections */ - unsigned int expecting; /* Unique ID that identifies this conntrack*/ unsigned int id; - /* Helper. if any */ - struct nf_conntrack_helper *helper; - /* features - nat, helper, ... used by allocating system */ u_int32_t features; - /* Storage reserved for other modules: */ - - union nf_conntrack_proto proto; - #if defined(CONFIG_NF_CONNTRACK_MARK) u_int32_t mark; #endif - /* These members are dynamically allocated. */ - - union nf_conntrack_help *help; + /* Storage reserved for other modules: */ + union nf_conntrack_proto proto; - /* Layer 3 dependent members. (ex: NAT) */ - union { - struct nf_conntrack_ipv4 *ipv4; - } l3proto; - void *data[0]; + /* features dynamically at the end: helper, nat (both optional) */ + char data[0]; }; struct nf_conntrack_expect @@ -373,10 +372,23 @@ nf_conntrack_expect_event(enum ip_conntrack_expect_events event, #define NF_CT_F_NUM 4 extern int -nf_conntrack_register_cache(u_int32_t features, const char *name, size_t size, - int (*init_conntrack)(struct nf_conn *, u_int32_t)); +nf_conntrack_register_cache(u_int32_t features, const char *name, size_t size); extern void nf_conntrack_unregister_cache(u_int32_t features); +/* valid combinations: + * basic: nf_conn, nf_conn .. nf_conn_help + * nat: nf_conn .. nf_conn_nat, nf_conn .. nf_conn_nat, nf_conn help + */ +static inline struct nf_conn_help *nfct_help(const struct nf_conn *ct) +{ + unsigned int offset = sizeof(struct nf_conn); + + if (!(ct->features & NF_CT_F_HELP)) + return NULL; + + return (struct nf_conn_help *) ((void *)ct + offset); +} + #endif /* __KERNEL__ */ #endif /* _NF_CONNTRACK_H */ -- cgit v1.2.2 From ba66c6e8b292997467128506f39fa6607e959050 Mon Sep 17 00:00:00 2001 From: Ian McDonald Date: Mon, 20 Mar 2006 17:56:56 -0800 Subject: [DCCP]: Set the default CCID according to kernel config selection Now CCID2 is the default, as stated in the RFC drafts, but we allow a config where just CCID3 is built, where CCID3 becomes the default. Signed-off-by: Ian McDonald Signed-off-by: Arnaldo Carvalho de Melo --- include/linux/dccp.h | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/dccp.h b/include/linux/dccp.h index f91c8a6240..a70d1a27e7 100644 --- a/include/linux/dccp.h +++ b/include/linux/dccp.h @@ -329,9 +329,18 @@ static inline unsigned int dccp_hdr_len(const struct sk_buff *skb) /* initial values for each feature */ #define DCCPF_INITIAL_SEQUENCE_WINDOW 100 -#define DCCPF_INITIAL_CCID 2 #define DCCPF_INITIAL_ACK_RATIO 2 + +#if defined(CONFIG_IP_DCCP_CCID2) || defined(CONFIG_IP_DCCP_CCID2_MODULE) +#define DCCPF_INITIAL_CCID 2 #define DCCPF_INITIAL_SEND_ACK_VECTOR 1 +#elif defined(CONFIG_IP_DCCP_CCID3) || defined(CONFIG_IP_DCCP_CCID3_MODULE) +#define DCCPF_INITIAL_CCID 3 +#define DCCPF_INITIAL_SEND_ACK_VECTOR 0 +#else +#error "At least one CCID must be built as the default" +#endif + /* FIXME: for now we're default to 1 but it should really be 0 */ #define DCCPF_INITIAL_SEND_NDP_COUNT 1 -- cgit v1.2.2 From 37f9f7334b86ffc3b8a1921842ae33cb9aa22ee3 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Mon, 20 Mar 2006 17:59:06 -0800 Subject: [NETFILTER]: xt_tables: add centralized error checking Introduce new functions for common match/target checks (private data size, valid hooks, valid tables and valid protocols) to get more consistent error reporting and to avoid each module duplicating them. Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- include/linux/netfilter/x_tables.h | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h index 6500d4e59d..b9c37e1e67 100644 --- a/include/linux/netfilter/x_tables.h +++ b/include/linux/netfilter/x_tables.h @@ -92,8 +92,6 @@ struct xt_match const char name[XT_FUNCTION_MAXNAMELEN-1]; - u_int8_t revision; - /* Return true or false: return FALSE and set *hotdrop = 1 to force immediate packet drop. */ /* Arguments changed since 2.6.9, as this must now handle @@ -120,6 +118,12 @@ struct xt_match /* Set this to THIS_MODULE if you are a module, otherwise NULL */ struct module *me; + + char *table; + unsigned int matchsize; + unsigned int hooks; + unsigned short proto; + u_int8_t revision; }; /* Registration hooks for targets. */ @@ -129,8 +133,6 @@ struct xt_target const char name[XT_FUNCTION_MAXNAMELEN-1]; - u_int8_t revision; - /* Returns verdict. Argument order changed since 2.6.9, as this must now handle non-linear skbs, using skb_copy_bits and skb_ip_make_writable. */ @@ -156,6 +158,12 @@ struct xt_target /* Set this to THIS_MODULE if you are a module, otherwise NULL */ struct module *me; + + char *table; + unsigned int targetsize; + unsigned int hooks; + unsigned short proto; + u_int8_t revision; }; /* Furniture shopping... */ @@ -207,6 +215,13 @@ extern void xt_unregister_target(int af, struct xt_target *target); extern int xt_register_match(int af, struct xt_match *target); extern void xt_unregister_match(int af, struct xt_match *target); +extern int xt_check_match(const struct xt_match *match, unsigned short family, + unsigned int size, const char *table, unsigned int hook, + unsigned short proto, int inv_proto); +extern int xt_check_target(const struct xt_target *target, unsigned short family, + unsigned int size, const char *table, unsigned int hook, + unsigned short proto, int inv_proto); + extern int xt_register_table(struct xt_table *table, struct xt_table_info *bootstrap, struct xt_table_info *newinfo); -- cgit v1.2.2 From 1c524830d0b39472f0278989bf1119750a5e234d Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Mon, 20 Mar 2006 18:02:15 -0800 Subject: [NETFILTER]: x_tables: pass registered match/target data to match/target functions This allows to make decisions based on the revision (and address family with a follow-up patch) at runtime. Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- include/linux/netfilter/x_tables.h | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h index b9c37e1e67..2fdbc4a446 100644 --- a/include/linux/netfilter/x_tables.h +++ b/include/linux/netfilter/x_tables.h @@ -100,6 +100,7 @@ struct xt_match int (*match)(const struct sk_buff *skb, const struct net_device *in, const struct net_device *out, + const struct xt_match *match, const void *matchinfo, int offset, unsigned int protoff, @@ -109,12 +110,14 @@ struct xt_match /* Should return true or false. */ int (*checkentry)(const char *tablename, const void *ip, + const struct xt_match *match, void *matchinfo, unsigned int matchinfosize, unsigned int hook_mask); /* Called when entry of this type deleted. */ - void (*destroy)(void *matchinfo, unsigned int matchinfosize); + void (*destroy)(const struct xt_match *match, void *matchinfo, + unsigned int matchinfosize); /* Set this to THIS_MODULE if you are a module, otherwise NULL */ struct module *me; @@ -140,6 +143,7 @@ struct xt_target const struct net_device *in, const struct net_device *out, unsigned int hooknum, + const struct xt_target *target, const void *targinfo, void *userdata); @@ -149,12 +153,14 @@ struct xt_target /* Should return true or false. */ int (*checkentry)(const char *tablename, const void *entry, + const struct xt_target *target, void *targinfo, unsigned int targinfosize, unsigned int hook_mask); /* Called when entry of this type deleted. */ - void (*destroy)(void *targinfo, unsigned int targinfosize); + void (*destroy)(const struct xt_target *target, void *targinfo, + unsigned int targinfosize); /* Set this to THIS_MODULE if you are a module, otherwise NULL */ struct module *me; -- cgit v1.2.2 From f2ffd9eeda82b476c034d733be08ecf6a87d2edf Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Mon, 20 Mar 2006 18:03:16 -0800 Subject: [NETFILTER]: Move ip6_masked_addrcmp to include/net/ipv6.h Replace netfilter's ip6_masked_addrcmp by a more efficient version in include/net/ipv6.h to make it usable without module dependencies. Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- include/net/ipv6.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'include') diff --git a/include/net/ipv6.h b/include/net/ipv6.h index 3b1d963d39..c893a1ce4b 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h @@ -282,6 +282,18 @@ static inline int ipv6_addr_cmp(const struct in6_addr *a1, const struct in6_addr return memcmp((const void *) a1, (const void *) a2, sizeof(struct in6_addr)); } +static inline int +ipv6_masked_addr_cmp(const struct in6_addr *a1, const struct in6_addr *m, + const struct in6_addr *a2) +{ + unsigned int i; + + for (i = 0; i < 4; i++) + if ((a1->s6_addr32[i] ^ a2->s6_addr32[i]) & m->s6_addr32[i]) + return 1; + return 0; +} + static inline void ipv6_addr_copy(struct in6_addr *a1, const struct in6_addr *a2) { memcpy((void *) a1, (const void *) a2, sizeof(struct in6_addr)); -- cgit v1.2.2 From c4b885139203d37f76662c37ae645fe8e0f4e4e5 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Mon, 20 Mar 2006 18:03:40 -0800 Subject: [NETFILTER]: x_tables: replace IPv4/IPv6 policy match by address family independant version Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- include/linux/netfilter/x_tables.h | 4 ++ include/linux/netfilter/xt_policy.h | 58 +++++++++++++++++++++++++ include/linux/netfilter_ipv4/ipt_policy.h | 69 +++++++----------------------- include/linux/netfilter_ipv6/ip6t_policy.h | 69 +++++++----------------------- 4 files changed, 94 insertions(+), 106 deletions(-) create mode 100644 include/linux/netfilter/xt_policy.h (limited to 'include') diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h index 2fdbc4a446..46a0f974f8 100644 --- a/include/linux/netfilter/x_tables.h +++ b/include/linux/netfilter/x_tables.h @@ -126,6 +126,8 @@ struct xt_match unsigned int matchsize; unsigned int hooks; unsigned short proto; + + unsigned short family; u_int8_t revision; }; @@ -169,6 +171,8 @@ struct xt_target unsigned int targetsize; unsigned int hooks; unsigned short proto; + + unsigned short family; u_int8_t revision; }; diff --git a/include/linux/netfilter/xt_policy.h b/include/linux/netfilter/xt_policy.h new file mode 100644 index 0000000000..a8132ec076 --- /dev/null +++ b/include/linux/netfilter/xt_policy.h @@ -0,0 +1,58 @@ +#ifndef _XT_POLICY_H +#define _XT_POLICY_H + +#define XT_POLICY_MAX_ELEM 4 + +enum xt_policy_flags +{ + XT_POLICY_MATCH_IN = 0x1, + XT_POLICY_MATCH_OUT = 0x2, + XT_POLICY_MATCH_NONE = 0x4, + XT_POLICY_MATCH_STRICT = 0x8, +}; + +enum xt_policy_modes +{ + XT_POLICY_MODE_TRANSPORT, + XT_POLICY_MODE_TUNNEL +}; + +struct xt_policy_spec +{ + u_int8_t saddr:1, + daddr:1, + proto:1, + mode:1, + spi:1, + reqid:1; +}; + +union xt_policy_addr +{ + struct in_addr a4; + struct in6_addr a6; +}; + +struct xt_policy_elem +{ + union xt_policy_addr saddr; + union xt_policy_addr smask; + union xt_policy_addr daddr; + union xt_policy_addr dmask; + u_int32_t spi; + u_int32_t reqid; + u_int8_t proto; + u_int8_t mode; + + struct xt_policy_spec match; + struct xt_policy_spec invert; +}; + +struct xt_policy_info +{ + struct xt_policy_elem pol[XT_POLICY_MAX_ELEM]; + u_int16_t flags; + u_int16_t len; +}; + +#endif /* _XT_POLICY_H */ diff --git a/include/linux/netfilter_ipv4/ipt_policy.h b/include/linux/netfilter_ipv4/ipt_policy.h index a3f6eff39d..b9478a2553 100644 --- a/include/linux/netfilter_ipv4/ipt_policy.h +++ b/include/linux/netfilter_ipv4/ipt_policy.h @@ -1,58 +1,21 @@ #ifndef _IPT_POLICY_H #define _IPT_POLICY_H -#define IPT_POLICY_MAX_ELEM 4 - -enum ipt_policy_flags -{ - IPT_POLICY_MATCH_IN = 0x1, - IPT_POLICY_MATCH_OUT = 0x2, - IPT_POLICY_MATCH_NONE = 0x4, - IPT_POLICY_MATCH_STRICT = 0x8, -}; - -enum ipt_policy_modes -{ - IPT_POLICY_MODE_TRANSPORT, - IPT_POLICY_MODE_TUNNEL -}; - -struct ipt_policy_spec -{ - u_int8_t saddr:1, - daddr:1, - proto:1, - mode:1, - spi:1, - reqid:1; -}; - -union ipt_policy_addr -{ - struct in_addr a4; - struct in6_addr a6; -}; - -struct ipt_policy_elem -{ - union ipt_policy_addr saddr; - union ipt_policy_addr smask; - union ipt_policy_addr daddr; - union ipt_policy_addr dmask; - u_int32_t spi; - u_int32_t reqid; - u_int8_t proto; - u_int8_t mode; - - struct ipt_policy_spec match; - struct ipt_policy_spec invert; -}; - -struct ipt_policy_info -{ - struct ipt_policy_elem pol[IPT_POLICY_MAX_ELEM]; - u_int16_t flags; - u_int16_t len; -}; +#define IPT_POLICY_MAX_ELEM XT_POLICY_MAX_ELEM + +/* ipt_policy_flags */ +#define IPT_POLICY_MATCH_IN XT_POLICY_MATCH_IN +#define IPT_POLICY_MATCH_OUT XT_POLICY_MATCH_OUT +#define IPT_POLICY_MATCH_NONE XT_POLICY_MATCH_NONE +#define IPT_POLICY_MATCH_STRICT XT_POLICY_MATCH_STRICT + +/* ipt_policy_modes */ +#define IPT_POLICY_MODE_TRANSPORT XT_POLICY_MODE_TRANSPORT +#define IPT_POLICY_MODE_TUNNEL XT_POLICY_MODE_TUNNEL + +#define ipt_policy_spec xt_policy_spec +#define ipt_policy_addr xt_policy_addr +#define ipt_policy_elem xt_policy_elem +#define ipt_policy_info xt_policy_info #endif /* _IPT_POLICY_H */ diff --git a/include/linux/netfilter_ipv6/ip6t_policy.h b/include/linux/netfilter_ipv6/ip6t_policy.h index 671bd81830..6bab3163d2 100644 --- a/include/linux/netfilter_ipv6/ip6t_policy.h +++ b/include/linux/netfilter_ipv6/ip6t_policy.h @@ -1,58 +1,21 @@ #ifndef _IP6T_POLICY_H #define _IP6T_POLICY_H -#define IP6T_POLICY_MAX_ELEM 4 - -enum ip6t_policy_flags -{ - IP6T_POLICY_MATCH_IN = 0x1, - IP6T_POLICY_MATCH_OUT = 0x2, - IP6T_POLICY_MATCH_NONE = 0x4, - IP6T_POLICY_MATCH_STRICT = 0x8, -}; - -enum ip6t_policy_modes -{ - IP6T_POLICY_MODE_TRANSPORT, - IP6T_POLICY_MODE_TUNNEL -}; - -struct ip6t_policy_spec -{ - u_int8_t saddr:1, - daddr:1, - proto:1, - mode:1, - spi:1, - reqid:1; -}; - -union ip6t_policy_addr -{ - struct in_addr a4; - struct in6_addr a6; -}; - -struct ip6t_policy_elem -{ - union ip6t_policy_addr saddr; - union ip6t_policy_addr smask; - union ip6t_policy_addr daddr; - union ip6t_policy_addr dmask; - u_int32_t spi; - u_int32_t reqid; - u_int8_t proto; - u_int8_t mode; - - struct ip6t_policy_spec match; - struct ip6t_policy_spec invert; -}; - -struct ip6t_policy_info -{ - struct ip6t_policy_elem pol[IP6T_POLICY_MAX_ELEM]; - u_int16_t flags; - u_int16_t len; -}; +#define IP6T_POLICY_MAX_ELEM XT_POLICY_MAX_ELEM + +/* ip6t_policy_flags */ +#define IP6T_POLICY_MATCH_IN XT_POLICY_MATCH_IN +#define IP6T_POLICY_MATCH_OUT XT_POLICY_MATCH_OUT +#define IP6T_POLICY_MATCH_NONE XT_POLICY_MATCH_NONE +#define IP6T_POLICY_MATCH_STRICT XT_POLICY_MATCH_STRICT + +/* ip6t_policy_modes */ +#define IP6T_POLICY_MODE_TRANSPORT XT_POLICY_MODE_TRANSPORT +#define IP6T_POLICY_MODE_TUNNEL XT_POLICY_MODE_TUNNEL + +#define ip6t_policy_spec xt_policy_spec +#define ip6t_policy_addr xt_policy_addr +#define ip6t_policy_elem xt_policy_elem +#define ip6t_policy_info xt_policy_info #endif /* _IP6T_POLICY_H */ -- cgit v1.2.2 From a24276924875802853b5bdc12c56d29f1c1bbc79 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Mon, 20 Mar 2006 18:03:59 -0800 Subject: [NETFILTER]: ctnetlink: avoid unneccessary event message generation Avoid unneccessary event message generation by checking for netlink listeners before building a message. Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- include/linux/netfilter/nfnetlink.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/netfilter/nfnetlink.h b/include/linux/netfilter/nfnetlink.h index 934a2479f1..9f5b12cf48 100644 --- a/include/linux/netfilter/nfnetlink.h +++ b/include/linux/netfilter/nfnetlink.h @@ -164,6 +164,7 @@ extern void nfattr_parse(struct nfattr *tb[], int maxattr, __res; \ }) +extern int nfnetlink_has_listeners(unsigned int group); extern int nfnetlink_send(struct sk_buff *skb, u32 pid, unsigned group, int echo); extern int nfnetlink_unicast(struct sk_buff *skb, u_int32_t pid, int flags); -- cgit v1.2.2 From 4277a083ecd2c8771058641132bcecea04ca6608 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Mon, 20 Mar 2006 18:52:01 -0800 Subject: [NETLINK]: Add netlink_has_listeners for avoiding unneccessary event message generation Keep a bitmask of multicast groups with subscribed listeners to let netlink users check for listeners before generating multicast messages. Queries don't perform any locking, which may result in false positives, it is guaranteed however that any new subscriptions are visible before bind() or setsockopt() return. Signed-off-by: Patrick McHardy ACKed-by: Jamal Hadi Salim Signed-off-by: David S. Miller --- include/linux/netlink.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/netlink.h b/include/linux/netlink.h index c256ebe2a7..f8f3d1c927 100644 --- a/include/linux/netlink.h +++ b/include/linux/netlink.h @@ -151,6 +151,7 @@ struct netlink_skb_parms extern struct sock *netlink_kernel_create(int unit, unsigned int groups, void (*input)(struct sock *sk, int len), struct module *module); extern void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err); +extern int netlink_has_listeners(struct sock *sk, unsigned int group); extern int netlink_unicast(struct sock *ssk, struct sk_buff *skb, __u32 pid, int nonblock); extern int netlink_broadcast(struct sock *ssk, struct sk_buff *skb, __u32 pid, __u32 group, gfp_t allocation); -- cgit v1.2.2 From f8cd54884e675dfaf0c86cc7c088adb6ca9d7638 Mon Sep 17 00:00:00 2001 From: Jamal Hadi Salim Date: Mon, 20 Mar 2006 19:15:11 -0800 Subject: [IPSEC]: Sync series - core changes This patch provides the core functionality needed for sync events for ipsec. Derived work of Krisztian KOVACS Signed-off-by: Jamal Hadi Salim Signed-off-by: David S. Miller --- include/linux/sysctl.h | 2 ++ include/linux/xfrm.h | 30 ++++++++++++++++++++++++++++++ include/net/xfrm.h | 44 +++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 75 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index 6e8880ea49..b686548f32 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -261,6 +261,8 @@ enum NET_CORE_DEV_WEIGHT=17, NET_CORE_SOMAXCONN=18, NET_CORE_BUDGET=19, + NET_CORE_AEVENT_ETIME=20, + NET_CORE_AEVENT_RSEQTH=21, }; /* /proc/sys/net/ethernet */ diff --git a/include/linux/xfrm.h b/include/linux/xfrm.h index 82fbb758e2..b54a12940e 100644 --- a/include/linux/xfrm.h +++ b/include/linux/xfrm.h @@ -156,6 +156,10 @@ enum { XFRM_MSG_FLUSHPOLICY, #define XFRM_MSG_FLUSHPOLICY XFRM_MSG_FLUSHPOLICY + XFRM_MSG_NEWAE, +#define XFRM_MSG_NEWAE XFRM_MSG_NEWAE + XFRM_MSG_GETAE, +#define XFRM_MSG_GETAE XFRM_MSG_GETAE __XFRM_MSG_MAX }; #define XFRM_MSG_MAX (__XFRM_MSG_MAX - 1) @@ -194,6 +198,21 @@ struct xfrm_encap_tmpl { xfrm_address_t encap_oa; }; +/* AEVENT flags */ +enum xfrm_ae_ftype_t { + XFRM_AE_UNSPEC, + XFRM_AE_RTHR=1, /* replay threshold*/ + XFRM_AE_RVAL=2, /* replay value */ + XFRM_AE_LVAL=4, /* lifetime value */ + XFRM_AE_ETHR=8, /* expiry timer threshold */ + XFRM_AE_CR=16, /* Event cause is replay update */ + XFRM_AE_CE=32, /* Event cause is timer expiry */ + XFRM_AE_CU=64, /* Event cause is policy update */ + __XFRM_AE_MAX + +#define XFRM_AE_MAX (__XFRM_AE_MAX - 1) +}; + /* Netlink message attributes. */ enum xfrm_attr_type_t { XFRMA_UNSPEC, @@ -205,6 +224,10 @@ enum xfrm_attr_type_t { XFRMA_SA, XFRMA_POLICY, XFRMA_SEC_CTX, /* struct xfrm_sec_ctx */ + XFRMA_LTIME_VAL, + XFRMA_REPLAY_VAL, + XFRMA_REPLAY_THRESH, + XFRMA_ETIMER_THRESH, __XFRMA_MAX #define XFRMA_MAX (__XFRMA_MAX - 1) @@ -235,6 +258,11 @@ struct xfrm_usersa_id { __u8 proto; }; +struct xfrm_aevent_id { + __u32 flags; + struct xfrm_usersa_id sa_id; +}; + struct xfrm_userspi_info { struct xfrm_usersa_info info; __u32 min; @@ -306,6 +334,8 @@ enum xfrm_nlgroups { #define XFRMNLGRP_SA XFRMNLGRP_SA XFRMNLGRP_POLICY, #define XFRMNLGRP_POLICY XFRMNLGRP_POLICY + XFRMNLGRP_AEVENTS, +#define XFRMNLGRP_AEVENTS XFRMNLGRP_AEVENTS __XFRMNLGRP_MAX }; #define XFRMNLGRP_MAX (__XFRMNLGRP_MAX - 1) diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 8d362c49b8..bc005e62e4 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -20,6 +20,10 @@ #define XFRM_ALIGN8(len) (((len) + 7) & ~7) +extern struct sock *xfrm_nl; +extern u32 sysctl_xfrm_aevent_etime; +extern u32 sysctl_xfrm_aevent_rseqth; + extern struct semaphore xfrm_cfg_sem; /* Organization of SPD aka "XFRM rules" @@ -135,6 +139,16 @@ struct xfrm_state /* State for replay detection */ struct xfrm_replay_state replay; + /* Replay detection state at the time we sent the last notification */ + struct xfrm_replay_state preplay; + + /* Replay detection notification settings */ + u32 replay_maxage; + u32 replay_maxdiff; + + /* Replay detection notification timer */ + struct timer_list rtimer; + /* Statistics */ struct xfrm_stats stats; @@ -169,6 +183,7 @@ struct km_event u32 hard; u32 proto; u32 byid; + u32 aevent; } data; u32 seq; @@ -305,7 +320,21 @@ struct xfrm_policy struct xfrm_tmpl xfrm_vec[XFRM_MAX_DEPTH]; }; -#define XFRM_KM_TIMEOUT 30 +#define XFRM_KM_TIMEOUT 30 +/* which seqno */ +#define XFRM_REPLAY_SEQ 1 +#define XFRM_REPLAY_OSEQ 2 +#define XFRM_REPLAY_SEQ_MASK 3 +/* what happened */ +#define XFRM_REPLAY_UPDATE XFRM_AE_CR +#define XFRM_REPLAY_TIMEOUT XFRM_AE_CE + +/* default aevent timeout in units of 100ms */ +#define XFRM_AE_ETIME 10 +/* Async Event timer multiplier */ +#define XFRM_AE_ETH_M 10 +/* default seq threshold size */ +#define XFRM_AE_SEQT_SIZE 2 struct xfrm_mgr { @@ -865,6 +894,7 @@ extern int xfrm_state_delete(struct xfrm_state *x); extern void xfrm_state_flush(u8 proto); extern int xfrm_replay_check(struct xfrm_state *x, u32 seq); extern void xfrm_replay_advance(struct xfrm_state *x, u32 seq); +extern void xfrm_replay_notify(struct xfrm_state *x, int event); extern int xfrm_state_check(struct xfrm_state *x, struct sk_buff *skb); extern int xfrm_state_mtu(struct xfrm_state *x, int mtu); extern int xfrm_init_state(struct xfrm_state *x); @@ -965,4 +995,16 @@ static inline int xfrm_policy_id2dir(u32 index) return index & 7; } +static inline int xfrm_aevent_is_on(void) +{ + return netlink_has_listeners(xfrm_nl,XFRMNLGRP_AEVENTS); +} + +static inline void xfrm_aevent_doreplay(struct xfrm_state *x) +{ + if (xfrm_aevent_is_on()) + xfrm_replay_notify(x, XFRM_REPLAY_UPDATE); +} + + #endif /* _NET_XFRM_H */ -- cgit v1.2.2 From 980ebd25794f0f87ac32844e2c73e9e81f0a72ba Mon Sep 17 00:00:00 2001 From: Jamal Hadi Salim Date: Mon, 20 Mar 2006 19:16:40 -0800 Subject: [IPSEC]: Sync series - acquire insert This introduces a feature similar to the one described in RFC 2367: " ... the application needing an SA sends a PF_KEY SADB_ACQUIRE message down to the Key Engine, which then either returns an error or sends a similar SADB_ACQUIRE message up to one or more key management applications capable of creating such SAs. ... ... The third is where an application-layer consumer of security associations (e.g. an OSPFv2 or RIPv2 daemon) needs a security association. Send an SADB_ACQUIRE message from a user process to the kernel. The kernel returns an SADB_ACQUIRE message to registered sockets. The user-level consumer waits for an SADB_UPDATE or SADB_ADD message for its particular type, and then can use that association by using SADB_GET messages. " An app such as OSPF could then use ipsec KM to get keys Signed-off-by: Jamal Hadi Salim Signed-off-by: David S. Miller --- include/net/xfrm.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/net/xfrm.h b/include/net/xfrm.h index bc005e62e4..30a940b147 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -214,10 +214,10 @@ extern int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo); extern int xfrm_policy_unregister_afinfo(struct xfrm_policy_afinfo *afinfo); extern void km_policy_notify(struct xfrm_policy *xp, int dir, struct km_event *c); extern void km_state_notify(struct xfrm_state *x, struct km_event *c); - #define XFRM_ACQ_EXPIRES 30 struct xfrm_tmpl; +extern int km_query(struct xfrm_state *x, struct xfrm_tmpl *t, struct xfrm_policy *pol); struct xfrm_state_afinfo { unsigned short family; rwlock_t lock; -- cgit v1.2.2 From 53bc6b4d29c07664f3abe029b7e6878a1067899a Mon Sep 17 00:00:00 2001 From: Jamal Hadi Salim Date: Mon, 20 Mar 2006 19:17:03 -0800 Subject: [IPSEC]: Sync series - SA expires This patch allows a user to insert SA expires. This is useful to do on an HA backup for the case of byte counts but may not be very useful for the case of time based expiry. Signed-off-by: Jamal Hadi Salim Signed-off-by: David S. Miller --- include/net/xfrm.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include') diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 30a940b147..d409c9d5e2 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -218,6 +218,9 @@ extern void km_state_notify(struct xfrm_state *x, struct km_event *c); struct xfrm_tmpl; extern int km_query(struct xfrm_state *x, struct xfrm_tmpl *t, struct xfrm_policy *pol); +extern void km_state_expired(struct xfrm_state *x, int hard, u32 pid); +extern int __xfrm_state_delete(struct xfrm_state *x); + struct xfrm_state_afinfo { unsigned short family; rwlock_t lock; -- cgit v1.2.2 From 6c5c8ca7ff20523e427b955aa84cef407934710f Mon Sep 17 00:00:00 2001 From: Jamal Hadi Salim Date: Mon, 20 Mar 2006 19:17:25 -0800 Subject: [IPSEC]: Sync series - policy expires This is similar to the SA expire insertion patch - only it inserts expires for SP. Signed-off-by: Jamal Hadi Salim Signed-off-by: David S. Miller --- include/net/xfrm.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/net/xfrm.h b/include/net/xfrm.h index d409c9d5e2..156f52ef8a 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -957,7 +957,7 @@ extern void xfrm_init_pmtu(struct dst_entry *dst); extern wait_queue_head_t km_waitq; extern int km_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, u16 sport); -extern void km_policy_expired(struct xfrm_policy *pol, int dir, int hard); +extern void km_policy_expired(struct xfrm_policy *pol, int dir, int hard, u32 pid); extern void xfrm_input_init(void); extern int xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, u32 *spi, u32 *seq); -- cgit v1.2.2 From 91f0ebf7b6d5cb2b6e818d48587566144821babe Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 20 Mar 2006 19:21:44 -0800 Subject: [DCCP] CCID: Improve CCID infrastructure 1. No need for ->ccid_init nor ->ccid_exit, this is what module_{init,exit} does and anynways neither ccid2 nor ccid3 were using it. 2. Rename struct ccid to struct ccid_operations and introduce struct ccid with a pointer to ccid_operations and rigth after it the rx or tx private state. 3. Remove the pointer to the state of the half connections from struct dccp_sock, now its derived thru ccid_priv() from the ccid pointer. Now we also can implement the setsockopt for changing the CCID easily as no ccid init routines can affect struct dccp_sock in any way that prevents other CCIDs from working if a CCID switch operation is asked by apps. Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: David S. Miller --- include/linux/dccp.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include') diff --git a/include/linux/dccp.h b/include/linux/dccp.h index a70d1a27e7..bdd756cc60 100644 --- a/include/linux/dccp.h +++ b/include/linux/dccp.h @@ -478,8 +478,6 @@ struct dccp_sock { __u32 dccps_mss_cache; struct dccp_options dccps_options; struct dccp_ackvec *dccps_hc_rx_ackvec; - void *dccps_hc_rx_ccid_private; - void *dccps_hc_tx_ccid_private; struct ccid *dccps_hc_rx_ccid; struct ccid *dccps_hc_tx_ccid; struct dccp_options_received dccps_options_received; -- cgit v1.2.2 From a193a4abdd1f742a57f3f70b6a83c3e536876e97 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Mon, 20 Mar 2006 19:23:05 -0800 Subject: [NETFILTER]: Fix skb->nf_bridge lifetime issues The bridge netfilter code simulates the NF_IP_PRE_ROUTING hook and skips the real hook by registering with high priority and returning NF_STOP if skb->nf_bridge is present and the BRNF_NF_BRIDGE_PREROUTING flag is not set. The flag is only set during the simulated hook. Because skb->nf_bridge is only freed when the packet is destroyed, the packet will not only skip the first invocation of NF_IP_PRE_ROUTING, but in the case of tunnel devices on top of the bridge also all further ones. Forwarded packets from a bridge encapsulated by a tunnel device and sent as locally outgoing packet will also still have the incorrect bridge information from the input path attached. We already have nf_reset calls on all RX/TX paths of tunnel devices, so simply reset the nf_bridge field there too. As an added bonus, the bridge information for locally delivered packets is now also freed when the packet is queued to a socket. Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- include/linux/skbuff.h | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) (limited to 'include') diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 838ce0fdce..1a2611030d 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -1351,16 +1351,6 @@ static inline void nf_conntrack_put_reasm(struct sk_buff *skb) kfree_skb(skb); } #endif -static inline void nf_reset(struct sk_buff *skb) -{ - nf_conntrack_put(skb->nfct); - skb->nfct = NULL; -#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) - nf_conntrack_put_reasm(skb->nfct_reasm); - skb->nfct_reasm = NULL; -#endif -} - #ifdef CONFIG_BRIDGE_NETFILTER static inline void nf_bridge_put(struct nf_bridge_info *nf_bridge) { @@ -1373,6 +1363,20 @@ static inline void nf_bridge_get(struct nf_bridge_info *nf_bridge) atomic_inc(&nf_bridge->use); } #endif /* CONFIG_BRIDGE_NETFILTER */ +static inline void nf_reset(struct sk_buff *skb) +{ + nf_conntrack_put(skb->nfct); + skb->nfct = NULL; +#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) + nf_conntrack_put_reasm(skb->nfct_reasm); + skb->nfct_reasm = NULL; +#endif +#ifdef CONFIG_BRIDGE_NETFILTER + nf_bridge_put(skb->nf_bridge); + skb->nf_bridge = NULL; +#endif +} + #else /* CONFIG_NETFILTER */ static inline void nf_reset(struct sk_buff *skb) {} #endif /* CONFIG_NETFILTER */ -- cgit v1.2.2 From 60fe62e789076ae7c13f7ffb35fec4b24802530d Mon Sep 17 00:00:00 2001 From: Andrea Bittau Date: Mon, 20 Mar 2006 19:23:32 -0800 Subject: [DCCP]: sparse endianness annotations This also fixes the layout of dccp_hdr short sequence numbers, problem was not fatal now as we only support long (48 bits) sequence numbers. Signed-off-by: Andrea Bittau Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: Al Viro Signed-off-by: David S. Miller --- include/linux/dccp.h | 52 +++++++++++++++++++++------------------------------- 1 file changed, 21 insertions(+), 31 deletions(-) (limited to 'include') diff --git a/include/linux/dccp.h b/include/linux/dccp.h index bdd756cc60..496dbad8e8 100644 --- a/include/linux/dccp.h +++ b/include/linux/dccp.h @@ -18,7 +18,7 @@ * @dccph_seq - sequence number high or low order 24 bits, depends on dccph_x */ struct dccp_hdr { - __u16 dccph_sport, + __be16 dccph_sport, dccph_dport; __u8 dccph_doff; #if defined(__LITTLE_ENDIAN_BITFIELD) @@ -32,18 +32,18 @@ struct dccp_hdr { #endif __u16 dccph_checksum; #if defined(__LITTLE_ENDIAN_BITFIELD) - __u32 dccph_x:1, + __u8 dccph_x:1, dccph_type:4, - dccph_reserved:3, - dccph_seq:24; + dccph_reserved:3; #elif defined(__BIG_ENDIAN_BITFIELD) - __u32 dccph_reserved:3, + __u8 dccph_reserved:3, dccph_type:4, - dccph_x:1, - dccph_seq:24; + dccph_x:1; #else #error "Adjust your defines" #endif + __u8 dccph_seq2; + __be16 dccph_seq; }; /** @@ -52,7 +52,7 @@ struct dccp_hdr { * @dccph_seq_low - low 24 bits of a 48 bit seq packet */ struct dccp_hdr_ext { - __u32 dccph_seq_low; + __be32 dccph_seq_low; }; /** @@ -62,7 +62,7 @@ struct dccp_hdr_ext { * @dccph_req_options - list of options (must be a multiple of 32 bits */ struct dccp_hdr_request { - __u32 dccph_req_service; + __be32 dccph_req_service; }; /** * struct dccp_hdr_ack_bits - acknowledgment bits common to most packets @@ -71,9 +71,9 @@ struct dccp_hdr_request { * @dccph_resp_ack_nr_low - 48 bit ack number low order bits, contains GSR */ struct dccp_hdr_ack_bits { - __u32 dccph_reserved1:8, - dccph_ack_nr_high:24; - __u32 dccph_ack_nr_low; + __be16 dccph_reserved1; + __be16 dccph_ack_nr_high; + __be32 dccph_ack_nr_low; }; /** * struct dccp_hdr_response - Conection initiation response header @@ -85,7 +85,7 @@ struct dccp_hdr_ack_bits { */ struct dccp_hdr_response { struct dccp_hdr_ack_bits dccph_resp_ack; - __u32 dccph_resp_service; + __be32 dccph_resp_service; }; /** @@ -269,16 +269,12 @@ static inline unsigned int dccp_basic_hdr_len(const struct sk_buff *skb) static inline __u64 dccp_hdr_seq(const struct sk_buff *skb) { const struct dccp_hdr *dh = dccp_hdr(skb); -#if defined(__LITTLE_ENDIAN_BITFIELD) - __u64 seq_nr = ntohl(dh->dccph_seq << 8); -#elif defined(__BIG_ENDIAN_BITFIELD) - __u64 seq_nr = ntohl(dh->dccph_seq); -#else -#error "Adjust your defines" -#endif + __u64 seq_nr = ntohs(dh->dccph_seq); if (dh->dccph_x != 0) seq_nr = (seq_nr << 32) + ntohl(dccp_hdrx(skb)->dccph_seq_low); + else + seq_nr += (u32)dh->dccph_seq2 << 16; return seq_nr; } @@ -296,13 +292,7 @@ static inline struct dccp_hdr_ack_bits *dccp_hdr_ack_bits(const struct sk_buff * static inline u64 dccp_hdr_ack_seq(const struct sk_buff *skb) { const struct dccp_hdr_ack_bits *dhack = dccp_hdr_ack_bits(skb); -#if defined(__LITTLE_ENDIAN_BITFIELD) - return (((u64)ntohl(dhack->dccph_ack_nr_high << 8)) << 32) + ntohl(dhack->dccph_ack_nr_low); -#elif defined(__BIG_ENDIAN_BITFIELD) - return (((u64)ntohl(dhack->dccph_ack_nr_high)) << 32) + ntohl(dhack->dccph_ack_nr_low); -#else -#error "Adjust your defines" -#endif + return ((u64)ntohs(dhack->dccph_ack_nr_high) << 32) + ntohl(dhack->dccph_ack_nr_low); } static inline struct dccp_hdr_response *dccp_hdr_response(struct sk_buff *skb) @@ -387,7 +377,7 @@ struct dccp_request_sock { struct inet_request_sock dreq_inet_rsk; __u64 dreq_iss; __u64 dreq_isr; - __u32 dreq_service; + __be32 dreq_service; }; static inline struct dccp_request_sock *dccp_rsk(const struct request_sock *req) @@ -415,13 +405,13 @@ enum dccp_role { struct dccp_service_list { __u32 dccpsl_nr; - __u32 dccpsl_list[0]; + __be32 dccpsl_list[0]; }; #define DCCP_SERVICE_INVALID_VALUE htonl((__u32)-1) static inline int dccp_list_has_service(const struct dccp_service_list *sl, - const u32 service) + const __be32 service) { if (likely(sl != NULL)) { u32 i = sl->dccpsl_nr; @@ -467,7 +457,7 @@ struct dccp_sock { __u64 dccps_gss; __u64 dccps_gsr; __u64 dccps_gar; - __u32 dccps_service; + __be32 dccps_service; struct dccp_service_list *dccps_service_list; struct timeval dccps_timestamp_time; __u32 dccps_timestamp_echo; -- cgit v1.2.2 From 93ce20928f6e197707add8f670ae0cd029107e8f Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 20 Mar 2006 19:23:58 -0800 Subject: [DCCP]: Make CCID2 be the default As per the draft. This fixes the build when netfilter dccp components are built and dccp isn't. Thanks to Reuben Farrelly for reporting this. The following changesets will introduce /proc/sys/net/dccp/defaults/ to give more flexibility to DCCP developers and testers while apps doesn't use setsockopt to specify the desired CCID, etc. Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: David S. Miller --- include/linux/dccp.h | 9 --------- 1 file changed, 9 deletions(-) (limited to 'include') diff --git a/include/linux/dccp.h b/include/linux/dccp.h index 496dbad8e8..e35f680f90 100644 --- a/include/linux/dccp.h +++ b/include/linux/dccp.h @@ -320,17 +320,8 @@ static inline unsigned int dccp_hdr_len(const struct sk_buff *skb) /* initial values for each feature */ #define DCCPF_INITIAL_SEQUENCE_WINDOW 100 #define DCCPF_INITIAL_ACK_RATIO 2 - -#if defined(CONFIG_IP_DCCP_CCID2) || defined(CONFIG_IP_DCCP_CCID2_MODULE) #define DCCPF_INITIAL_CCID 2 #define DCCPF_INITIAL_SEND_ACK_VECTOR 1 -#elif defined(CONFIG_IP_DCCP_CCID3) || defined(CONFIG_IP_DCCP_CCID3_MODULE) -#define DCCPF_INITIAL_CCID 3 -#define DCCPF_INITIAL_SEND_ACK_VECTOR 0 -#else -#error "At least one CCID must be built as the default" -#endif - /* FIXME: for now we're default to 1 but it should really be 0 */ #define DCCPF_INITIAL_SEND_NDP_COUNT 1 -- cgit v1.2.2 From e55d912f5b75723159348a7fc7692f869a86636a Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 20 Mar 2006 19:25:02 -0800 Subject: [DCCP] feat: Introduce sysctls for the default features [root@qemu ~]# for a in /proc/sys/net/dccp/default/* ; do echo $a ; cat $a ; done /proc/sys/net/dccp/default/ack_ratio 2 /proc/sys/net/dccp/default/rx_ccid 3 /proc/sys/net/dccp/default/send_ackvec 1 /proc/sys/net/dccp/default/send_ndp 1 /proc/sys/net/dccp/default/seq_window 100 /proc/sys/net/dccp/default/tx_ccid 3 [root@qemu ~]# So if wanting to test ccid3 as the tx CCID one can just do: [root@qemu ~]# echo 3 > /proc/sys/net/dccp/default/tx_ccid [root@qemu ~]# echo 2 > /proc/sys/net/dccp/default/rx_ccid [root@qemu ~]# cat /proc/sys/net/dccp/default/[tr]x_ccid 2 3 [root@qemu ~]# Of course we also need the setsockopt for each app to tell its preferences, but for testing or defining something other than CCID2 as the default for apps that don't explicitely set their preference the sysctl interface is handy. Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: David S. Miller --- include/linux/sysctl.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'include') diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index b686548f32..dfcf449afc 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -211,6 +211,7 @@ enum NET_SCTP=17, NET_LLC=18, NET_NETFILTER=19, + NET_DCCP=20, }; /* /proc/sys/kernel/random */ @@ -571,6 +572,21 @@ enum { __NET_NEIGH_MAX }; +/* /proc/sys/net/dccp */ +enum { + NET_DCCP_DEFAULT=1, +}; + +/* /proc/sys/net/dccp/default */ +enum { + NET_DCCP_DEFAULT_SEQ_WINDOW = 1, + NET_DCCP_DEFAULT_RX_CCID = 2, + NET_DCCP_DEFAULT_TX_CCID = 3, + NET_DCCP_DEFAULT_ACK_RATIO = 4, + NET_DCCP_DEFAULT_SEND_ACKVEC = 5, + NET_DCCP_DEFAULT_SEND_NDP = 6, +}; + /* /proc/sys/net/ipx */ enum { NET_IPX_PPROP_BROADCASTING=1, -- cgit v1.2.2 From 4bf07ef3fd5db2df7d1899fcf9c67d2263ead2e2 Mon Sep 17 00:00:00 2001 From: Jamal Hadi Salim Date: Mon, 20 Mar 2006 21:25:50 -0800 Subject: [XFRM]: Rearrange struct xfrm_aevent_id for better compatibility. struct xfrm_aevent_id needs to be 32-bit + 64-bit align friendly. Based upon suggestions from Yoshifuji. Signed-off-by: Jamal Hadi Salim Signed-off-by: David S. Miller --- include/linux/xfrm.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/xfrm.h b/include/linux/xfrm.h index b54a12940e..6b42cc474c 100644 --- a/include/linux/xfrm.h +++ b/include/linux/xfrm.h @@ -259,8 +259,8 @@ struct xfrm_usersa_id { }; struct xfrm_aevent_id { - __u32 flags; struct xfrm_usersa_id sa_id; + __u32 flags; }; struct xfrm_userspi_info { -- cgit v1.2.2 From 231d06ae826664b83369166449144304859a62fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=F6rn=20Engel?= Date: Mon, 20 Mar 2006 21:28:35 -0800 Subject: [NET]: Uninline kfree_skb and allow NULL argument MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit o Uninline kfree_skb, which saves some 15k of object code on my notebook. o Allow kfree_skb to be called with a NULL argument. Subsequent patches can remove conditional from drivers and further reduce source and object size. Signed-off-by: Jörn Engel Signed-off-by: David S. Miller --- include/linux/skbuff.h | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) (limited to 'include') diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 1a2611030d..75c963103b 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -304,6 +304,7 @@ struct sk_buff { #include +extern void kfree_skb(struct sk_buff *skb); extern void __kfree_skb(struct sk_buff *skb); extern struct sk_buff *__alloc_skb(unsigned int size, gfp_t priority, int fclone); @@ -403,22 +404,6 @@ static inline struct sk_buff *skb_get(struct sk_buff *skb) * atomic change. */ -/** - * kfree_skb - free an sk_buff - * @skb: buffer to free - * - * Drop a reference to the buffer and free it if the usage count has - * hit zero. - */ -static inline void kfree_skb(struct sk_buff *skb) -{ - if (likely(atomic_read(&skb->users) == 1)) - smp_rmb(); - else if (likely(!atomic_dec_and_test(&skb->users))) - return; - __kfree_skb(skb); -} - /** * skb_cloned - is the buffer a clone * @skb: buffer to check -- cgit v1.2.2 From 1d541ddd74802cfa0eb8a3864668851f6cd79bdf Mon Sep 17 00:00:00 2001 From: Benjamin LaHaise Date: Mon, 20 Mar 2006 21:31:51 -0800 Subject: [AF_UNIX]: scm: better initialization Instead of doing a memset then initialization of the fields of the scm structure, just initialize all the members explicitly. Prevent reloading of current on x86 and x86-64 by storing the value in a local variable for subsequent dereferences. This is worth a ~7KB/s increase in af_unix bandwidth. Note that we avoid the issues surrounding potentially uninitialized members of the ucred structure by constructing a struct ucred instead of assigning the members individually, which forces the compiler to zero any padding. [ I modified the patch not to use the aggregate assignment since gcc-3.4.x and earlier cannot optimize that properly at all even though gcc-4.0.x and later can -DaveM ] Signed-off-by: Benjamin LaHaise Signed-off-by: David S. Miller --- include/net/scm.h | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/net/scm.h b/include/net/scm.h index c3fa3d5ab6..540619cb71 100644 --- a/include/net/scm.h +++ b/include/net/scm.h @@ -37,10 +37,12 @@ static __inline__ void scm_destroy(struct scm_cookie *scm) static __inline__ int scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm) { - memset(scm, 0, sizeof(*scm)); - scm->creds.uid = current->uid; - scm->creds.gid = current->gid; - scm->creds.pid = current->tgid; + struct task_struct *p = current; + scm->creds.uid = p->uid; + scm->creds.gid = p->gid; + scm->creds.pid = p->tgid; + scm->fp = NULL; + scm->seq = 0; if (msg->msg_controllen <= 0) return 0; return __scm_send(sock, msg, scm); -- cgit v1.2.2 From 0e7b13685f9a06949ea3070c97c0f0085a08cd37 Mon Sep 17 00:00:00 2001 From: John Heffner Date: Mon, 20 Mar 2006 21:32:58 -0800 Subject: [TCP] mtu probing: move tcp-specific data out of inet_connection_sock This moves some TCP-specific MTU probing state out of inet_connection_sock back to tcp_sock. Signed-off-by: John Heffner Signed-off-by: David S. Miller --- include/linux/tcp.h | 6 ++++++ include/net/inet_connection_sock.h | 2 -- 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/linux/tcp.h b/include/linux/tcp.h index f2bb239685..542d39596b 100644 --- a/include/linux/tcp.h +++ b/include/linux/tcp.h @@ -343,6 +343,12 @@ struct tcp_sock { __u32 seq; __u32 time; } rcvq_space; + +/* TCP-specific MTU probe information. */ + struct { + __u32 probe_seq_start; + __u32 probe_seq_end; + } mtu_probe; }; static inline struct tcp_sock *tcp_sk(const struct sock *sk) diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h index b3abe33f4e..4e5a9ff99f 100644 --- a/include/net/inet_connection_sock.h +++ b/include/net/inet_connection_sock.h @@ -114,8 +114,6 @@ struct inet_connection_sock { /* Information on the current probe. */ int probe_size; - __u32 probe_seq_start; - __u32 probe_seq_end; } icsk_mtup; u32 icsk_ca_priv[16]; #define ICSK_CA_PRIV_SIZE (16 * sizeof(u32)) -- cgit v1.2.2 From c4d9390941aee136fd35bb38eb1d6de4e3b1487d Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 20 Mar 2006 22:01:03 -0800 Subject: [ICSK]: Introduce inet_csk_ctl_sock_create Consolidating open coded sequences in tcp and dccp, v4 and v6. Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: David S. Miller --- include/net/inet_connection_sock.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include') diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h index 4e5a9ff99f..363a067403 100644 --- a/include/net/inet_connection_sock.h +++ b/include/net/inet_connection_sock.h @@ -321,4 +321,8 @@ extern void inet_csk_listen_stop(struct sock *sk); extern void inet_csk_addr2sockaddr(struct sock *sk, struct sockaddr *uaddr); +extern int inet_csk_ctl_sock_create(struct socket **sock, + unsigned short family, + unsigned short type, + unsigned char protocol); #endif /* _INET_CONNECTION_SOCK_H */ -- cgit v1.2.2 From 0ac81ae34ec8898e7eb1388fe21e3cee7b626a88 Mon Sep 17 00:00:00 2001 From: David Basden Date: Mon, 20 Mar 2006 22:21:10 -0800 Subject: [IRDA]: TOIM3232 dongle support Here goes a patch for supporting TOIM3232 based serial IrDA dongles. The code is based on the tekram dongle code. It's been tested with a TOIM3232 based IRWave 320S dongle. It may work for TOIM4232 dongles, although it's not been tested. Signed-off-by: David Basden Signed-off-by: Samuel Ortiz Signed-off-by: David S. Miller --- include/linux/irda.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/irda.h b/include/linux/irda.h index 95dee174cd..09d8f105a5 100644 --- a/include/linux/irda.h +++ b/include/linux/irda.h @@ -76,6 +76,7 @@ typedef enum { IRDA_MCP2120_DONGLE = 9, IRDA_ACT200L_DONGLE = 10, IRDA_MA600_DONGLE = 11, + IRDA_TOIM3232_DONGLE = 12, } IRDA_DONGLE; /* Protocol types to be used for SOCK_DGRAM */ -- cgit v1.2.2 From 6756ae4b4e97aba48c042b4aa6b77a18f507d2cb Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 20 Mar 2006 22:23:58 -0800 Subject: [NET]: Convert RTNL to mutex. This patch turns the RTNL from a semaphore to a new 2.6.16 mutex and gets rid of some of the leftover legacy. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- include/linux/rtnetlink.h | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) (limited to 'include') diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h index edccefb451..d263853a8f 100644 --- a/include/linux/rtnetlink.h +++ b/include/linux/rtnetlink.h @@ -907,6 +907,7 @@ struct tcamsg #ifdef __KERNEL__ #include +#include extern size_t rtattr_strlcpy(char *dest, const struct rtattr *rta, size_t size); static __inline__ int rtattr_strcmp(const struct rtattr *rta, const char *str) @@ -1038,24 +1039,17 @@ __rta_reserve(struct sk_buff *skb, int attrtype, int attrlen) extern void rtmsg_ifinfo(int type, struct net_device *dev, unsigned change); -extern struct semaphore rtnl_sem; - -#define rtnl_shlock() down(&rtnl_sem) -#define rtnl_shlock_nowait() down_trylock(&rtnl_sem) - -#define rtnl_shunlock() do { up(&rtnl_sem); \ - if (rtnl && rtnl->sk_receive_queue.qlen) \ - rtnl->sk_data_ready(rtnl, 0); \ - } while(0) - +/* RTNL is used as a global lock for all changes to network configuration */ extern void rtnl_lock(void); -extern int rtnl_lock_interruptible(void); extern void rtnl_unlock(void); +extern int rtnl_trylock(void); + extern void rtnetlink_init(void); +extern void __rtnl_unlock(void); #define ASSERT_RTNL() do { \ - if (unlikely(down_trylock(&rtnl_sem) == 0)) { \ - up(&rtnl_sem); \ + if (unlikely(rtnl_trylock())) { \ + rtnl_unlock(); \ printk(KERN_ERR "RTNL: assertion failed at %s (%d)\n", \ __FILE__, __LINE__); \ dump_stack(); \ -- cgit v1.2.2 From c5ecd62c25400a3c6856e009f84257d5bd03f03b Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Mon, 20 Mar 2006 22:25:41 -0800 Subject: [NET]: Move destructor from neigh->ops to neigh_params struct neigh_ops currently has a destructor field, which no in-kernel drivers outside of infiniband use. The infiniband/ulp/ipoib in-tree driver stashes some info in the neighbour structure (the results of the second-stage lookup from ARP results to real link-level path), and it uses neigh->ops->destructor to get a callback so it can clean up this extra info when a neighbour is freed. We've run into problems with this: since the destructor is in an ops field that is shared between neighbours that may belong to different net devices, there's no way to set/clear it safely. The following patch moves this field to neigh_parms where it can be safely set, together with its twin neigh_setup. Two additional patches in the patch series update ipoib to use this new interface. Signed-off-by: Michael S. Tsirkin Signed-off-by: Roland Dreier Signed-off-by: David S. Miller --- include/net/neighbour.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/net/neighbour.h b/include/net/neighbour.h index 6fa9ae1907..b0666d6629 100644 --- a/include/net/neighbour.h +++ b/include/net/neighbour.h @@ -68,6 +68,7 @@ struct neigh_parms struct net_device *dev; struct neigh_parms *next; int (*neigh_setup)(struct neighbour *); + void (*neigh_destructor)(struct neighbour *); struct neigh_table *tbl; void *sysctl_table; @@ -145,7 +146,6 @@ struct neighbour struct neigh_ops { int family; - void (*destructor)(struct neighbour *); void (*solicit)(struct neighbour *, struct sk_buff*); void (*error_report)(struct neighbour *, struct sk_buff*); int (*output)(struct sk_buff*); -- cgit v1.2.2 From 99cae7fca1311573f2777b8ceaa8a5abd6e9b04e Mon Sep 17 00:00:00 2001 From: Alpt Date: Mon, 20 Mar 2006 22:26:17 -0800 Subject: [NET] rtnetlink: Add RTPROT entry for Netsukuku. The Netsukuku daemon is using the same number to mark its routes, you can see it here: http://hinezumilabs.org/cgi-bin/viewcvs.cgi/netsukuku/src/krnl_route.h?rev=HEAD&content-type=text/vnd.viewcvs-markup Signed-off-by: David S. Miller --- include/linux/rtnetlink.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h index d263853a8f..d572d53763 100644 --- a/include/linux/rtnetlink.h +++ b/include/linux/rtnetlink.h @@ -199,6 +199,7 @@ enum #define RTPROT_BIRD 12 /* BIRD */ #define RTPROT_DNROUTED 13 /* DECnet routing daemon */ #define RTPROT_XORP 14 /* XORP */ +#define RTPROT_NTK 15 /* Netsukuku */ /* rtm_scope -- cgit v1.2.2 From d9ab5ad12b0d865bdb1b750d81192d34465541e9 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Mon, 20 Mar 2006 22:27:35 -0800 Subject: [TG3]: Add 5787 and 5754 basic support Add basic support for 2 new chips 5787 and 5754. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- include/linux/pci_ids.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include') diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index a3a09cceb0..b9810ddf43 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -1861,14 +1861,18 @@ #define PCI_DEVICE_ID_TIGON3_5780 0x166a #define PCI_DEVICE_ID_TIGON3_5780S 0x166b #define PCI_DEVICE_ID_TIGON3_5705F 0x166e +#define PCI_DEVICE_ID_TIGON3_5754M 0x1672 #define PCI_DEVICE_ID_TIGON3_5750 0x1676 #define PCI_DEVICE_ID_TIGON3_5751 0x1677 #define PCI_DEVICE_ID_TIGON3_5715 0x1678 #define PCI_DEVICE_ID_TIGON3_5715S 0x1679 +#define PCI_DEVICE_ID_TIGON3_5754 0x167a #define PCI_DEVICE_ID_TIGON3_5750M 0x167c #define PCI_DEVICE_ID_TIGON3_5751M 0x167d #define PCI_DEVICE_ID_TIGON3_5751F 0x167e +#define PCI_DEVICE_ID_TIGON3_5787M 0x1693 #define PCI_DEVICE_ID_TIGON3_5782 0x1696 +#define PCI_DEVICE_ID_TIGON3_5787 0x169b #define PCI_DEVICE_ID_TIGON3_5788 0x169c #define PCI_DEVICE_ID_TIGON3_5789 0x169d #define PCI_DEVICE_ID_TIGON3_5702X 0x16a6 -- cgit v1.2.2 From 153330618691694af64f39fb56c9de051862380e Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 20 Mar 2006 22:32:28 -0800 Subject: [NET]: dev_put/dev_hold cleanup Get rid of the old __dev_put macro that is just a hold over from pre 2.6 kernel. And turn dev_hold into an inline instead of a macro. Signed-off-by: Stephen Hemminger Signed-off-by: Andrew Morton Signed-off-by: David S. Miller --- include/linux/netdevice.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index b825be201b..950dc55e51 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -712,8 +712,10 @@ static inline void dev_put(struct net_device *dev) atomic_dec(&dev->refcnt); } -#define __dev_put(dev) atomic_dec(&(dev)->refcnt) -#define dev_hold(dev) atomic_inc(&(dev)->refcnt) +static inline void dev_hold(struct net_device *dev) +{ + atomic_inc(&dev->refcnt); +} /* Carrier loss detection, dial on demand. The functions netif_carrier_on * and _off may be called from IRQ context, but it is caller -- cgit v1.2.2 From 4a3e2f711a00a1feb72ae12fdc749da10179d185 Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Mon, 20 Mar 2006 22:33:17 -0800 Subject: [NET] sem2mutex: net/ Semaphore to mutex conversion. The conversion was generated via scripts, and the result was validated automatically via a script as well. Signed-off-by: Arjan van de Ven Signed-off-by: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: David S. Miller --- include/net/xfrm.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 156f52ef8a..786371365f 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -24,7 +25,7 @@ extern struct sock *xfrm_nl; extern u32 sysctl_xfrm_aevent_etime; extern u32 sysctl_xfrm_aevent_rseqth; -extern struct semaphore xfrm_cfg_sem; +extern struct mutex xfrm_cfg_mutex; /* Organization of SPD aka "XFRM rules" ------------------------------------ -- cgit v1.2.2 From 57b47a53ec4a67691ba32cff5768e8d78fa6c67f Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 20 Mar 2006 22:35:41 -0800 Subject: [NET]: sem2mutex part 2 Semaphore to mutex conversion. The conversion was generated via scripts, and the result was validated automatically via a script as well. Signed-off-by: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: David S. Miller --- include/linux/sunrpc/svcsock.h | 2 +- include/net/af_unix.h | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/linux/sunrpc/svcsock.h b/include/linux/sunrpc/svcsock.h index d33c6face0..b4acb3d37c 100644 --- a/include/linux/sunrpc/svcsock.h +++ b/include/linux/sunrpc/svcsock.h @@ -36,7 +36,7 @@ struct svc_sock { struct list_head sk_deferred; /* deferred requests that need to * be revisted */ - struct semaphore sk_sem; /* to serialize sending data */ + struct mutex sk_mutex; /* to serialize sending data */ int (*sk_recvfrom)(struct svc_rqst *rqstp); int (*sk_sendto)(struct svc_rqst *rqstp); diff --git a/include/net/af_unix.h b/include/net/af_unix.h index bfc1779fc7..427dac94bc 100644 --- a/include/net/af_unix.h +++ b/include/net/af_unix.h @@ -4,6 +4,7 @@ #include #include #include +#include #include extern void unix_inflight(struct file *fp); @@ -71,7 +72,7 @@ struct unix_sock { struct unix_address *addr; struct dentry *dentry; struct vfsmount *mnt; - struct semaphore readsem; + struct mutex readlock; struct sock *peer; struct sock *other; struct sock *gc_tree; -- cgit v1.2.2 From abd596a4b68b6526c2676233e10602dd9660e9d7 Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Mon, 20 Mar 2006 22:39:47 -0800 Subject: [IPV4] ARP: Alloc acceptance of unsolicited ARP via netdevice sysctl. Signed-off-by: Neil Horman Signed-off-by: David S. Miller --- include/linux/inetdevice.h | 1 + include/linux/sysctl.h | 1 + 2 files changed, 2 insertions(+) (limited to 'include') diff --git a/include/linux/inetdevice.h b/include/linux/inetdevice.h index fd7af86151..92297ff24e 100644 --- a/include/linux/inetdevice.h +++ b/include/linux/inetdevice.h @@ -25,6 +25,7 @@ struct ipv4_devconf int arp_filter; int arp_announce; int arp_ignore; + int arp_accept; int medium_id; int no_xfrm; int no_policy; diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index dfcf449afc..8754568a75 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -456,6 +456,7 @@ enum NET_IPV4_CONF_ARP_ANNOUNCE=18, NET_IPV4_CONF_ARP_IGNORE=19, NET_IPV4_CONF_PROMOTE_SECONDARIES=20, + NET_IPV4_CONF_ARP_ACCEPT=21, __NET_IPV4_CONF_MAX }; -- cgit v1.2.2 From 15d99e02babae8bc20b836917ace07d93e318149 Mon Sep 17 00:00:00 2001 From: Rick Jones Date: Mon, 20 Mar 2006 22:40:29 -0800 Subject: [TCP]: sysctl to allow TCP window > 32767 sans wscale Back in the dark ages, we had to be conservative and only allow 15-bit window fields if the window scale option was not negotiated. Some ancient stacks used a signed 16-bit quantity for the window field of the TCP header and would get confused. Those days are long gone, so we can use the full 16-bits by default now. There is a sysctl added so that we can still interact with such old stacks Signed-off-by: Rick Jones Signed-off-by: David S. Miller --- include/linux/sysctl.h | 1 + include/net/tcp.h | 1 + 2 files changed, 2 insertions(+) (limited to 'include') diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index 8754568a75..76eaeff76f 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -402,6 +402,7 @@ enum NET_IPV4_IPFRAG_MAX_DIST=112, NET_TCP_MTU_PROBING=113, NET_TCP_BASE_MSS=114, + NET_IPV4_TCP_WORKAROUND_SIGNED_WINDOWS=115, }; enum { diff --git a/include/net/tcp.h b/include/net/tcp.h index 16879fa560..457e224de4 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -224,6 +224,7 @@ extern int sysctl_tcp_tso_win_divisor; extern int sysctl_tcp_abc; extern int sysctl_tcp_mtu_probing; extern int sysctl_tcp_base_mss; +extern int sysctl_tcp_workaround_signed_windows; extern atomic_t tcp_memory_allocated; extern atomic_t tcp_sockets_allocated; -- cgit v1.2.2 From be33690d8fcf40377f16193c463681170eb6b295 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Mon, 20 Mar 2006 22:40:54 -0800 Subject: [XFRM]: Fix aevent related crash When xfrm_user isn't loaded xfrm_nl is NULL, which makes IPsec crash because xfrm_aevent_is_on passes the NULL pointer to netlink_has_listeners as socket. A second problem is that the xfrm_nl pointer is not cleared when the socket is releases at module unload time. Protect references of xfrm_nl from outside of xfrm_user by RCU, check that the socket is present in xfrm_aevent_is_on and set it to NULL when unloading xfrm_user. Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- include/net/xfrm.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 786371365f..61b7504fc2 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -1001,7 +1001,15 @@ static inline int xfrm_policy_id2dir(u32 index) static inline int xfrm_aevent_is_on(void) { - return netlink_has_listeners(xfrm_nl,XFRMNLGRP_AEVENTS); + struct sock *nlsk; + int ret = 0; + + rcu_read_lock(); + nlsk = rcu_dereference(xfrm_nl); + if (nlsk) + ret = netlink_has_listeners(nlsk, XFRMNLGRP_AEVENTS); + rcu_read_unlock(); + return ret; } static inline void xfrm_aevent_doreplay(struct xfrm_state *x) -- cgit v1.2.2 From 2c7946a7bf45ae86736ab3b43d0085e43947945c Mon Sep 17 00:00:00 2001 From: Catherine Zhang Date: Mon, 20 Mar 2006 22:41:23 -0800 Subject: [SECURITY]: TCP/UDP getpeersec This patch implements an application of the LSM-IPSec networking controls whereby an application can determine the label of the security association its TCP or UDP sockets are currently connected to via getsockopt and the auxiliary data mechanism of recvmsg. Patch purpose: This patch enables a security-aware application to retrieve the security context of an IPSec security association a particular TCP or UDP socket is using. The application can then use this security context to determine the security context for processing on behalf of the peer at the other end of this connection. In the case of UDP, the security context is for each individual packet. An example application is the inetd daemon, which could be modified to start daemons running at security contexts dependent on the remote client. Patch design approach: - Design for TCP The patch enables the SELinux LSM to set the peer security context for a socket based on the security context of the IPSec security association. The application may retrieve this context using getsockopt. When called, the kernel determines if the socket is a connected (TCP_ESTABLISHED) TCP socket and, if so, uses the dst_entry cache on the socket to retrieve the security associations. If a security association has a security context, the context string is returned, as for UNIX domain sockets. - Design for UDP Unlike TCP, UDP is connectionless. This requires a somewhat different API to retrieve the peer security context. With TCP, the peer security context stays the same throughout the connection, thus it can be retrieved at any time between when the connection is established and when it is torn down. With UDP, each read/write can have different peer and thus the security context might change every time. As a result the security context retrieval must be done TOGETHER with the packet retrieval. The solution is to build upon the existing Unix domain socket API for retrieving user credentials. Linux offers the API for obtaining user credentials via ancillary messages (i.e., out of band/control messages that are bundled together with a normal message). Patch implementation details: - Implementation for TCP The security context can be retrieved by applications using getsockopt with the existing SO_PEERSEC flag. As an example (ignoring error checking): getsockopt(sockfd, SOL_SOCKET, SO_PEERSEC, optbuf, &optlen); printf("Socket peer context is: %s\n", optbuf); The SELinux function, selinux_socket_getpeersec, is extended to check for labeled security associations for connected (TCP_ESTABLISHED == sk->sk_state) TCP sockets only. If so, the socket has a dst_cache of struct dst_entry values that may refer to security associations. If these have security associations with security contexts, the security context is returned. getsockopt returns a buffer that contains a security context string or the buffer is unmodified. - Implementation for UDP To retrieve the security context, the application first indicates to the kernel such desire by setting the IP_PASSSEC option via getsockopt. Then the application retrieves the security context using the auxiliary data mechanism. An example server application for UDP should look like this: toggle = 1; toggle_len = sizeof(toggle); setsockopt(sockfd, SOL_IP, IP_PASSSEC, &toggle, &toggle_len); recvmsg(sockfd, &msg_hdr, 0); if (msg_hdr.msg_controllen > sizeof(struct cmsghdr)) { cmsg_hdr = CMSG_FIRSTHDR(&msg_hdr); if (cmsg_hdr->cmsg_len <= CMSG_LEN(sizeof(scontext)) && cmsg_hdr->cmsg_level == SOL_IP && cmsg_hdr->cmsg_type == SCM_SECURITY) { memcpy(&scontext, CMSG_DATA(cmsg_hdr), sizeof(scontext)); } } ip_setsockopt is enhanced with a new socket option IP_PASSSEC to allow a server socket to receive security context of the peer. A new ancillary message type SCM_SECURITY. When the packet is received we get the security context from the sec_path pointer which is contained in the sk_buff, and copy it to the ancillary message space. An additional LSM hook, selinux_socket_getpeersec_udp, is defined to retrieve the security context from the SELinux space. The existing function, selinux_socket_getpeersec does not suit our purpose, because the security context is copied directly to user space, rather than to kernel space. Testing: We have tested the patch by setting up TCP and UDP connections between applications on two machines using the IPSec policies that result in labeled security associations being built. For TCP, we can then extract the peer security context using getsockopt on either end. For UDP, the receiving end can retrieve the security context using the auxiliary data mechanism of recvmsg. Signed-off-by: Catherine Zhang Acked-by: James Morris Acked-by: Herbert Xu Signed-off-by: David S. Miller --- include/linux/in.h | 1 + include/linux/security.h | 25 +++++++++++++++++++------ include/linux/socket.h | 1 + 3 files changed, 21 insertions(+), 6 deletions(-) (limited to 'include') diff --git a/include/linux/in.h b/include/linux/in.h index ba35538401..94f557fa46 100644 --- a/include/linux/in.h +++ b/include/linux/in.h @@ -72,6 +72,7 @@ struct in_addr { #define IP_FREEBIND 15 #define IP_IPSEC_POLICY 16 #define IP_XFRM_POLICY 17 +#define IP_PASSSEC 18 /* BSD compatibility */ #define IP_RECVRETOPTS IP_RETOPTS diff --git a/include/linux/security.h b/include/linux/security.h index 7cbef482e1..b18eb8cfa6 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -1286,7 +1286,8 @@ struct security_operations { int (*socket_setsockopt) (struct socket * sock, int level, int optname); int (*socket_shutdown) (struct socket * sock, int how); int (*socket_sock_rcv_skb) (struct sock * sk, struct sk_buff * skb); - int (*socket_getpeersec) (struct socket *sock, char __user *optval, int __user *optlen, unsigned len); + int (*socket_getpeersec_stream) (struct socket *sock, char __user *optval, int __user *optlen, unsigned len); + int (*socket_getpeersec_dgram) (struct sk_buff *skb, char **secdata, u32 *seclen); int (*sk_alloc_security) (struct sock *sk, int family, gfp_t priority); void (*sk_free_security) (struct sock *sk); unsigned int (*sk_getsid) (struct sock *sk, struct flowi *fl, u8 dir); @@ -2741,10 +2742,16 @@ static inline int security_sock_rcv_skb (struct sock * sk, return security_ops->socket_sock_rcv_skb (sk, skb); } -static inline int security_socket_getpeersec(struct socket *sock, char __user *optval, - int __user *optlen, unsigned len) +static inline int security_socket_getpeersec_stream(struct socket *sock, char __user *optval, + int __user *optlen, unsigned len) { - return security_ops->socket_getpeersec(sock, optval, optlen, len); + return security_ops->socket_getpeersec_stream(sock, optval, optlen, len); +} + +static inline int security_socket_getpeersec_dgram(struct sk_buff *skb, char **secdata, + u32 *seclen) +{ + return security_ops->socket_getpeersec_dgram(skb, secdata, seclen); } static inline int security_sk_alloc(struct sock *sk, int family, gfp_t priority) @@ -2863,8 +2870,14 @@ static inline int security_sock_rcv_skb (struct sock * sk, return 0; } -static inline int security_socket_getpeersec(struct socket *sock, char __user *optval, - int __user *optlen, unsigned len) +static inline int security_socket_getpeersec_stream(struct socket *sock, char __user *optval, + int __user *optlen, unsigned len) +{ + return -ENOPROTOOPT; +} + +static inline int security_socket_getpeersec_dgram(struct sk_buff *skb, char **secdata, + u32 *seclen) { return -ENOPROTOOPT; } diff --git a/include/linux/socket.h b/include/linux/socket.h index b02dda4ee8..9ab2ddd802 100644 --- a/include/linux/socket.h +++ b/include/linux/socket.h @@ -150,6 +150,7 @@ __KINLINE struct cmsghdr * cmsg_nxthdr (struct msghdr *__msg, struct cmsghdr *__ #define SCM_RIGHTS 0x01 /* rw: access rights (array of int) */ #define SCM_CREDENTIALS 0x02 /* rw: struct ucred */ +#define SCM_SECURITY 0x03 /* rw: security label */ struct ucred { __u32 pid; -- cgit v1.2.2 From c4ea94ab3710eb2434abe2eab1a479c2dc01f8ac Mon Sep 17 00:00:00 2001 From: Steven Whitehouse Date: Mon, 20 Mar 2006 22:42:39 -0800 Subject: [DECnet]: Endian annotation and fixes for DECnet. The typedef for dn_address has been removed in favour of using __le16 or __u16 directly as appropriate. All the DECnet header files are updated accordingly. The byte ordering of dn_eth2dn() and dn_dn2eth() are both changed since just about all their callers wanted network order rather than host order, so the conversion is now done in the functions themselves. Several missed endianess conversions have been picked up during the conversion process. The nh_gw field in struct dn_fib_info has been changed from a 32 bit field to 16 bits as it ought to be. One or two cases of using htons rather than dn_htons in the routing code have been found and fixed. There are still a few warnings to fix, but this patch deals with the important cases. Signed-off-by: Steven Whitehouse Signed-off-by: Patrick Caulfield Signed-off-by: David S. Miller --- include/linux/dn.h | 44 ++++++++++----------- include/net/dn.h | 105 ++++++++++++++++++++++++------------------------- include/net/dn_dev.h | 88 ++++++++++++++++++++--------------------- include/net/dn_fib.h | 22 +++++------ include/net/dn_neigh.h | 4 +- include/net/dn_nsp.h | 72 ++++++++++++++++----------------- include/net/dn_route.h | 12 +++--- include/net/flow.h | 8 ++-- 8 files changed, 177 insertions(+), 178 deletions(-) (limited to 'include') diff --git a/include/linux/dn.h b/include/linux/dn.h index 782cae49e6..10b6a6fd58 100644 --- a/include/linux/dn.h +++ b/include/linux/dn.h @@ -71,17 +71,17 @@ struct dn_naddr { - unsigned short a_len; - unsigned char a_addr[DN_MAXADDL]; + __le16 a_len; + __u8 a_addr[DN_MAXADDL]; /* Two bytes little endian */ }; struct sockaddr_dn { - unsigned short sdn_family; - unsigned char sdn_flags; - unsigned char sdn_objnum; - unsigned short sdn_objnamel; - unsigned char sdn_objname[DN_MAXOBJL]; + __u16 sdn_family; + __u8 sdn_flags; + __u8 sdn_objnum; + __le16 sdn_objnamel; + __u8 sdn_objname[DN_MAXOBJL]; struct dn_naddr sdn_add; }; #define sdn_nodeaddrl sdn_add.a_len /* Node address length */ @@ -93,38 +93,38 @@ struct sockaddr_dn * DECnet set/get DSO_CONDATA, DSO_DISDATA (optional data) structure */ struct optdata_dn { - unsigned short opt_status; /* Extended status return */ + __le16 opt_status; /* Extended status return */ #define opt_sts opt_status - unsigned short opt_optl; /* Length of user data */ - unsigned char opt_data[16]; /* User data */ + __le16 opt_optl; /* Length of user data */ + __u8 opt_data[16]; /* User data */ }; struct accessdata_dn { - unsigned char acc_accl; - unsigned char acc_acc[DN_MAXACCL]; - unsigned char acc_passl; - unsigned char acc_pass[DN_MAXACCL]; - unsigned char acc_userl; - unsigned char acc_user[DN_MAXACCL]; + __u8 acc_accl; + __u8 acc_acc[DN_MAXACCL]; + __u8 acc_passl; + __u8 acc_pass[DN_MAXACCL]; + __u8 acc_userl; + __u8 acc_user[DN_MAXACCL]; }; /* * DECnet logical link information structure */ struct linkinfo_dn { - unsigned short idn_segsize; /* Segment size for link */ - unsigned char idn_linkstate; /* Logical link state */ + __le16 idn_segsize; /* Segment size for link */ + __u8 idn_linkstate; /* Logical link state */ }; /* * Ethernet address format (for DECnet) */ union etheraddress { - unsigned char dne_addr[6]; /* Full ethernet address */ + __u8 dne_addr[6]; /* Full ethernet address */ struct { - unsigned char dne_hiord[4]; /* DECnet HIORD prefix */ - unsigned char dne_nodeaddr[2]; /* DECnet node address */ + __u8 dne_hiord[4]; /* DECnet HIORD prefix */ + __u8 dne_nodeaddr[2]; /* DECnet node address */ } dne_remote; }; @@ -133,7 +133,7 @@ union etheraddress { * DECnet physical socket address format */ struct dn_addr { - unsigned short dna_family; /* AF_DECnet */ + __le16 dna_family; /* AF_DECnet */ union etheraddress dna_netaddr; /* DECnet ethernet address */ }; diff --git a/include/net/dn.h b/include/net/dn.h index a4b6168e1e..465b783027 100644 --- a/include/net/dn.h +++ b/include/net/dn.h @@ -6,10 +6,8 @@ #include #include -typedef unsigned short dn_address; - -#define dn_ntohs(x) le16_to_cpu((unsigned short)(x)) -#define dn_htons(x) cpu_to_le16((unsigned short)(x)) +#define dn_ntohs(x) le16_to_cpu(x) +#define dn_htons(x) cpu_to_le16(x) struct dn_scp /* Session Control Port */ { @@ -31,36 +29,36 @@ struct dn_scp /* Session Control Port */ #define DN_CL 15 /* Closed */ #define DN_CN 16 /* Closed Notification */ - unsigned short addrloc; - unsigned short addrrem; - unsigned short numdat; - unsigned short numoth; - unsigned short numoth_rcv; - unsigned short numdat_rcv; - unsigned short ackxmt_dat; - unsigned short ackxmt_oth; - unsigned short ackrcv_dat; - unsigned short ackrcv_oth; - unsigned char flowrem_sw; - unsigned char flowloc_sw; + __le16 addrloc; + __le16 addrrem; + __u16 numdat; + __u16 numoth; + __u16 numoth_rcv; + __u16 numdat_rcv; + __u16 ackxmt_dat; + __u16 ackxmt_oth; + __u16 ackrcv_dat; + __u16 ackrcv_oth; + __u8 flowrem_sw; + __u8 flowloc_sw; #define DN_SEND 2 #define DN_DONTSEND 1 #define DN_NOCHANGE 0 - unsigned short flowrem_dat; - unsigned short flowrem_oth; - unsigned short flowloc_dat; - unsigned short flowloc_oth; - unsigned char services_rem; - unsigned char services_loc; - unsigned char info_rem; - unsigned char info_loc; - - unsigned short segsize_rem; - unsigned short segsize_loc; - - unsigned char nonagle; - unsigned char multi_ireq; - unsigned char accept_mode; + __u16 flowrem_dat; + __u16 flowrem_oth; + __u16 flowloc_dat; + __u16 flowloc_oth; + __u8 services_rem; + __u8 services_loc; + __u8 info_rem; + __u8 info_loc; + + __u16 segsize_rem; + __u16 segsize_loc; + + __u8 nonagle; + __u8 multi_ireq; + __u8 accept_mode; unsigned long seg_total; /* Running total of current segment */ struct optdata_dn conndata_in; @@ -160,40 +158,41 @@ static inline struct dn_scp *DN_SK(struct sock *sk) */ #define DN_SKB_CB(skb) ((struct dn_skb_cb *)(skb)->cb) struct dn_skb_cb { - unsigned short dst; - unsigned short src; - unsigned short hops; - unsigned short dst_port; - unsigned short src_port; - unsigned char services; - unsigned char info; - unsigned char rt_flags; - unsigned char nsp_flags; - unsigned short segsize; - unsigned short segnum; - unsigned short xmit_count; + __le16 dst; + __le16 src; + __u16 hops; + __le16 dst_port; + __le16 src_port; + __u8 services; + __u8 info; + __u8 rt_flags; + __u8 nsp_flags; + __u16 segsize; + __u16 segnum; + __u16 xmit_count; unsigned long stamp; int iif; }; -static inline dn_address dn_eth2dn(unsigned char *ethaddr) +static inline __le16 dn_eth2dn(unsigned char *ethaddr) { - return ethaddr[4] | (ethaddr[5] << 8); + return dn_htons(ethaddr[4] | (ethaddr[5] << 8)); } -static inline dn_address dn_saddr2dn(struct sockaddr_dn *saddr) +static inline __le16 dn_saddr2dn(struct sockaddr_dn *saddr) { - return *(dn_address *)saddr->sdn_nodeaddr; + return *(__le16 *)saddr->sdn_nodeaddr; } -static inline void dn_dn2eth(unsigned char *ethaddr, dn_address addr) +static inline void dn_dn2eth(unsigned char *ethaddr, __le16 addr) { + __u16 a = dn_ntohs(addr); ethaddr[0] = 0xAA; ethaddr[1] = 0x00; ethaddr[2] = 0x04; ethaddr[3] = 0x00; - ethaddr[4] = (unsigned char)(addr & 0xff); - ethaddr[5] = (unsigned char)(addr >> 8); + ethaddr[4] = (__u8)(a & 0xff); + ethaddr[5] = (__u8)(a >> 8); } static inline void dn_sk_ports_copy(struct flowi *fl, struct dn_scp *scp) @@ -202,7 +201,7 @@ static inline void dn_sk_ports_copy(struct flowi *fl, struct dn_scp *scp) fl->uli_u.dnports.dport = scp->addrrem; fl->uli_u.dnports.objnum = scp->addr.sdn_objnum; if (fl->uli_u.dnports.objnum == 0) { - fl->uli_u.dnports.objnamel = scp->addr.sdn_objnamel; + fl->uli_u.dnports.objnamel = (__u8)dn_ntohs(scp->addr.sdn_objnamel); memcpy(fl->uli_u.dnports.objname, scp->addr.sdn_objname, 16); } } @@ -217,7 +216,7 @@ extern unsigned dn_mss_from_pmtu(struct net_device *dev, int mtu); extern struct sock *dn_sklist_find_listener(struct sockaddr_dn *addr); extern struct sock *dn_find_by_skb(struct sk_buff *skb); #define DN_ASCBUF_LEN 9 -extern char *dn_addr2asc(dn_address, char *); +extern char *dn_addr2asc(__u16, char *); extern int dn_destroy_timer(struct sock *sk); extern int dn_sockaddr2username(struct sockaddr_dn *addr, unsigned char *buf, unsigned char type); @@ -226,7 +225,7 @@ extern int dn_username2sockaddr(unsigned char *data, int len, struct sockaddr_dn extern void dn_start_slow_timer(struct sock *sk); extern void dn_stop_slow_timer(struct sock *sk); -extern dn_address decnet_address; +extern __le16 decnet_address; extern int decnet_debug_level; extern int decnet_time_wait; extern int decnet_dn_count; diff --git a/include/net/dn_dev.h b/include/net/dn_dev.h index 5a86e78081..cee46821dc 100644 --- a/include/net/dn_dev.h +++ b/include/net/dn_dev.h @@ -7,11 +7,11 @@ struct dn_dev; struct dn_ifaddr { struct dn_ifaddr *ifa_next; struct dn_dev *ifa_dev; - dn_address ifa_local; - dn_address ifa_address; - unsigned char ifa_flags; - unsigned char ifa_scope; - char ifa_label[IFNAMSIZ]; + __le16 ifa_local; + __le16 ifa_address; + __u8 ifa_flags; + __u8 ifa_scope; + char ifa_label[IFNAMSIZ]; }; #define DN_DEV_S_RU 0 /* Run - working normally */ @@ -91,7 +91,7 @@ struct dn_dev { struct timer_list timer; unsigned long t3; struct neigh_parms *neigh_parms; - unsigned char addr[ETH_ALEN]; + __u8 addr[ETH_ALEN]; struct neighbour *router; /* Default router on circuit */ struct neighbour *peer; /* Peer on pointopoint links */ unsigned long uptime; /* Time device went up in jiffies */ @@ -99,56 +99,56 @@ struct dn_dev { struct dn_short_packet { - unsigned char msgflg; - unsigned short dstnode; - unsigned short srcnode; - unsigned char forward; + __u8 msgflg; + __le16 dstnode; + __le16 srcnode; + __u8 forward; } __attribute__((packed)); struct dn_long_packet { - unsigned char msgflg; - unsigned char d_area; - unsigned char d_subarea; - unsigned char d_id[6]; - unsigned char s_area; - unsigned char s_subarea; - unsigned char s_id[6]; - unsigned char nl2; - unsigned char visit_ct; - unsigned char s_class; - unsigned char pt; + __u8 msgflg; + __u8 d_area; + __u8 d_subarea; + __u8 d_id[6]; + __u8 s_area; + __u8 s_subarea; + __u8 s_id[6]; + __u8 nl2; + __u8 visit_ct; + __u8 s_class; + __u8 pt; } __attribute__((packed)); /*------------------------- DRP - Routing messages ---------------------*/ struct endnode_hello_message { - unsigned char msgflg; - unsigned char tiver[3]; - unsigned char id[6]; - unsigned char iinfo; - unsigned short blksize; - unsigned char area; - unsigned char seed[8]; - unsigned char neighbor[6]; - unsigned short timer; - unsigned char mpd; - unsigned char datalen; - unsigned char data[2]; + __u8 msgflg; + __u8 tiver[3]; + __u8 id[6]; + __u8 iinfo; + __le16 blksize; + __u8 area; + __u8 seed[8]; + __u8 neighbor[6]; + __le16 timer; + __u8 mpd; + __u8 datalen; + __u8 data[2]; } __attribute__((packed)); struct rtnode_hello_message { - unsigned char msgflg; - unsigned char tiver[3]; - unsigned char id[6]; - unsigned char iinfo; - unsigned short blksize; - unsigned char priority; - unsigned char area; - unsigned short timer; - unsigned char mpd; + __u8 msgflg; + __u8 tiver[3]; + __u8 id[6]; + __u8 iinfo; + __le16 blksize; + __u8 priority; + __u8 area; + __le16 timer; + __u8 mpd; } __attribute__((packed)); @@ -169,12 +169,12 @@ extern void dn_dev_down(struct net_device *); extern int dn_dev_set_default(struct net_device *dev, int force); extern struct net_device *dn_dev_get_default(void); -extern int dn_dev_bind_default(dn_address *addr); +extern int dn_dev_bind_default(__le16 *addr); extern int register_dnaddr_notifier(struct notifier_block *nb); extern int unregister_dnaddr_notifier(struct notifier_block *nb); -static inline int dn_dev_islocal(struct net_device *dev, dn_address addr) +static inline int dn_dev_islocal(struct net_device *dev, __le16 addr) { struct dn_dev *dn_db = dev->dn_ptr; struct dn_ifaddr *ifa; diff --git a/include/net/dn_fib.h b/include/net/dn_fib.h index cd3c96d960..a15dcf0d5c 100644 --- a/include/net/dn_fib.h +++ b/include/net/dn_fib.h @@ -37,7 +37,7 @@ struct dn_fib_nh { int nh_weight; int nh_power; int nh_oif; - u32 nh_gw; + __le16 nh_gw; }; struct dn_fib_info { @@ -48,7 +48,7 @@ struct dn_fib_info { int fib_dead; unsigned fib_flags; int fib_protocol; - dn_address fib_prefsrc; + __le16 fib_prefsrc; __u32 fib_priority; __u32 fib_metrics[RTAX_MAX]; #define dn_fib_mtu fib_metrics[RTAX_MTU-1] @@ -71,15 +71,15 @@ struct dn_fib_info { #define DN_FIB_RES_OIF(res) (DN_FIB_RES_NH(res).nh_oif) typedef struct { - u16 datum; + __le16 datum; } dn_fib_key_t; typedef struct { - u16 datum; + __le16 datum; } dn_fib_hash_t; typedef struct { - u16 datum; + __u16 datum; } dn_fib_idx_t; struct dn_fib_node { @@ -126,11 +126,11 @@ extern int dn_fib_semantic_match(int type, struct dn_fib_info *fi, const struct flowi *fl, struct dn_fib_res *res); extern void dn_fib_release_info(struct dn_fib_info *fi); -extern u16 dn_fib_get_attr16(struct rtattr *attr, int attrlen, int type); +extern __le16 dn_fib_get_attr16(struct rtattr *attr, int attrlen, int type); extern void dn_fib_flush(void); extern void dn_fib_select_multipath(const struct flowi *fl, struct dn_fib_res *res); -extern int dn_fib_sync_down(dn_address local, struct net_device *dev, +extern int dn_fib_sync_down(__le16 local, struct net_device *dev, int force); extern int dn_fib_sync_up(struct net_device *dev); @@ -148,8 +148,8 @@ extern void dn_fib_table_cleanup(void); extern void dn_fib_rules_init(void); extern void dn_fib_rules_cleanup(void); extern void dn_fib_rule_put(struct dn_fib_rule *); -extern __u16 dn_fib_rules_policy(__u16 saddr, struct dn_fib_res *res, unsigned *flags); -extern unsigned dnet_addr_type(__u16 addr); +extern __le16 dn_fib_rules_policy(__le16 saddr, struct dn_fib_res *res, unsigned *flags); +extern unsigned dnet_addr_type(__le16 addr); extern int dn_fib_lookup(const struct flowi *fl, struct dn_fib_res *res); /* @@ -194,10 +194,10 @@ extern struct dn_fib_table *dn_fib_tables[]; #endif /* CONFIG_DECNET_ROUTER */ -static inline u16 dnet_make_mask(int n) +static inline __le16 dnet_make_mask(int n) { if (n) - return htons(~((1<<(16-n))-1)); + return dn_htons(~((1<<(16-n))-1)); return 0; } diff --git a/include/net/dn_neigh.h b/include/net/dn_neigh.h index 4b1eb038d6..4cb4ae7fb8 100644 --- a/include/net/dn_neigh.h +++ b/include/net/dn_neigh.h @@ -7,13 +7,13 @@ */ struct dn_neigh { struct neighbour n; - dn_address addr; + __le16 addr; unsigned long flags; #define DN_NDFLAG_R1 0x0001 /* Router L1 */ #define DN_NDFLAG_R2 0x0002 /* Router L2 */ #define DN_NDFLAG_P3 0x0004 /* Phase III Node */ unsigned long blksize; - unsigned char priority; + __u8 priority; }; extern void dn_neigh_init(void); diff --git a/include/net/dn_nsp.h b/include/net/dn_nsp.h index e6182b8626..96e816b697 100644 --- a/include/net/dn_nsp.h +++ b/include/net/dn_nsp.h @@ -72,77 +72,77 @@ extern struct sk_buff *dn_alloc_send_skb(struct sock *sk, size_t *size, int nobl struct nsp_data_seg_msg { - unsigned char msgflg; - unsigned short dstaddr; - unsigned short srcaddr; + __u8 msgflg; + __le16 dstaddr; + __le16 srcaddr; } __attribute__((packed)); struct nsp_data_opt_msg { - unsigned short acknum; - unsigned short segnum; - unsigned short lsflgs; + __le16 acknum; + __le16 segnum; + __le16 lsflgs; } __attribute__((packed)); struct nsp_data_opt_msg1 { - unsigned short acknum; - unsigned short segnum; + __le16 acknum; + __le16 segnum; } __attribute__((packed)); /* Acknowledgment Message (data/other data) */ struct nsp_data_ack_msg { - unsigned char msgflg; - unsigned short dstaddr; - unsigned short srcaddr; - unsigned short acknum; + __u8 msgflg; + __le16 dstaddr; + __le16 srcaddr; + __le16 acknum; } __attribute__((packed)); /* Connect Acknowledgment Message */ struct nsp_conn_ack_msg { - unsigned char msgflg; - unsigned short dstaddr; + __u8 msgflg; + __le16 dstaddr; } __attribute__((packed)); /* Connect Initiate/Retransmit Initiate/Connect Confirm */ struct nsp_conn_init_msg { - unsigned char msgflg; + __u8 msgflg; #define NSP_CI 0x18 /* Connect Initiate */ #define NSP_RCI 0x68 /* Retrans. Conn Init */ - unsigned short dstaddr; - unsigned short srcaddr; - unsigned char services; + __le16 dstaddr; + __le16 srcaddr; + __u8 services; #define NSP_FC_NONE 0x00 /* Flow Control None */ #define NSP_FC_SRC 0x04 /* Seg Req. Count */ #define NSP_FC_SCMC 0x08 /* Sess. Control Mess */ #define NSP_FC_MASK 0x0c /* FC type mask */ - unsigned char info; - unsigned short segsize; + __u8 info; + __le16 segsize; } __attribute__((packed)); /* Disconnect Initiate/Disconnect Confirm */ struct nsp_disconn_init_msg { - unsigned char msgflg; - unsigned short dstaddr; - unsigned short srcaddr; - unsigned short reason; + __u8 msgflg; + __le16 dstaddr; + __le16 srcaddr; + __le16 reason; } __attribute__((packed)); struct srcobj_fmt { - char format; - unsigned char task; - unsigned short grpcode; - unsigned short usrcode; - char dlen; + __u8 format; + __u8 task; + __le16 grpcode; + __le16 usrcode; + __u8 dlen; } __attribute__((packed)); /* @@ -150,7 +150,7 @@ struct srcobj_fmt * numbers used in NSP. Similar in operation to the functions * of the same name in TCP. */ -static __inline__ int dn_before(unsigned short seq1, unsigned short seq2) +static __inline__ int dn_before(__u16 seq1, __u16 seq2) { seq1 &= 0x0fff; seq2 &= 0x0fff; @@ -159,7 +159,7 @@ static __inline__ int dn_before(unsigned short seq1, unsigned short seq2) } -static __inline__ int dn_after(unsigned short seq1, unsigned short seq2) +static __inline__ int dn_after(__u16 seq1, __u16 seq2) { seq1 &= 0x0fff; seq2 &= 0x0fff; @@ -167,23 +167,23 @@ static __inline__ int dn_after(unsigned short seq1, unsigned short seq2) return (int)((seq2 - seq1) & 0x0fff) > 2048; } -static __inline__ int dn_equal(unsigned short seq1, unsigned short seq2) +static __inline__ int dn_equal(__u16 seq1, __u16 seq2) { return ((seq1 ^ seq2) & 0x0fff) == 0; } -static __inline__ int dn_before_or_equal(unsigned short seq1, unsigned short seq2) +static __inline__ int dn_before_or_equal(__u16 seq1, __u16 seq2) { return (dn_before(seq1, seq2) || dn_equal(seq1, seq2)); } -static __inline__ void seq_add(unsigned short *seq, unsigned short off) +static __inline__ void seq_add(__u16 *seq, __u16 off) { (*seq) += off; (*seq) &= 0x0fff; } -static __inline__ int seq_next(unsigned short seq1, unsigned short seq2) +static __inline__ int seq_next(__u16 seq1, __u16 seq2) { return dn_equal(seq1 + 1, seq2); } @@ -191,7 +191,7 @@ static __inline__ int seq_next(unsigned short seq1, unsigned short seq2) /* * Can we delay the ack ? */ -static __inline__ int sendack(unsigned short seq) +static __inline__ int sendack(__u16 seq) { return (int)((seq & 0x1000) ? 0 : 1); } diff --git a/include/net/dn_route.h b/include/net/dn_route.h index 5122da3f2e..76f957e258 100644 --- a/include/net/dn_route.h +++ b/include/net/dn_route.h @@ -71,12 +71,12 @@ struct dn_route { struct dn_route *rt_next; } u; - __u16 rt_saddr; - __u16 rt_daddr; - __u16 rt_gateway; - __u16 rt_local_src; /* Source used for forwarding packets */ - __u16 rt_src_map; - __u16 rt_dst_map; + __le16 rt_saddr; + __le16 rt_daddr; + __le16 rt_gateway; + __le16 rt_local_src; /* Source used for forwarding packets */ + __le16 rt_src_map; + __le16 rt_dst_map; unsigned rt_flags; unsigned rt_type; diff --git a/include/net/flow.h b/include/net/flow.h index ec7eb86eb2..04d89f7634 100644 --- a/include/net/flow.h +++ b/include/net/flow.h @@ -30,8 +30,8 @@ struct flowi { } ip6_u; struct { - __u16 daddr; - __u16 saddr; + __le16 daddr; + __le16 saddr; __u32 fwmark; __u8 scope; } dn_u; @@ -64,8 +64,8 @@ struct flowi { } icmpt; struct { - __u16 sport; - __u16 dport; + __le16 sport; + __le16 dport; __u8 objnum; __u8 objnamel; /* Not 16 bits since max val is 16 */ __u8 objname[16]; /* Not zero terminated */ -- cgit v1.2.2 From cbb042f9e1292434e3cacb90e67d8d381aeac5a9 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Mon, 20 Mar 2006 22:43:56 -0800 Subject: [NET]: Replace skb_pull/skb_postpull_rcsum with skb_pull_rcsum We're now starting to have quite a number of places that do skb_pull followed immediately by an skb_postpull_rcsum. We can merge these two operations into one function with skb_pull_rcsum. This makes sense since most pull operations on receive skb's need to update the checksum. I've decided to make this out-of-line since it is fairly big and the fast path where hardware checksums are enabled need to call csum_partial anyway. Since this is a brand new function we get to add an extra check on the len argument. As it is most callers of skb_pull ignore its return value which essentially means that there is no check on the len argument. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- include/linux/skbuff.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 75c963103b..613b9513f8 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -1159,12 +1159,14 @@ static inline int skb_linearize(struct sk_buff *skb, gfp_t gfp) */ static inline void skb_postpull_rcsum(struct sk_buff *skb, - const void *start, int len) + const void *start, unsigned int len) { if (skb->ip_summed == CHECKSUM_HW) skb->csum = csum_sub(skb->csum, csum_partial(start, len, 0)); } +unsigned char *skb_pull_rcsum(struct sk_buff *skb, unsigned int len); + /** * pskb_trim_rcsum - trim received skb and update checksum * @skb: buffer to trim -- cgit v1.2.2 From 3fdadf7d27e3fbcf72930941884387d1f4936f04 Mon Sep 17 00:00:00 2001 From: Dmitry Mishin Date: Mon, 20 Mar 2006 22:45:21 -0800 Subject: [NET]: {get|set}sockopt compatibility layer This patch extends {get|set}sockopt compatibility layer in order to move protocol specific parts to their place and avoid huge universal net/compat.c file in the future. Signed-off-by: Dmitry Mishin Signed-off-by: David S. Miller --- include/linux/net.h | 4 ++++ include/linux/netfilter.h | 9 +++++++++ include/net/inet_connection_sock.h | 6 ++++++ include/net/ip.h | 4 ++++ include/net/ipv6.h | 10 ++++++++++ include/net/sctp/structs.h | 10 ++++++++++ include/net/sock.h | 12 ++++++++++++ include/net/tcp.h | 6 ++++++ 8 files changed, 61 insertions(+) (limited to 'include') diff --git a/include/linux/net.h b/include/linux/net.h index 28195a2d8f..152fa6551f 100644 --- a/include/linux/net.h +++ b/include/linux/net.h @@ -149,6 +149,10 @@ struct proto_ops { int optname, char __user *optval, int optlen); int (*getsockopt)(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen); + int (*compat_setsockopt)(struct socket *sock, int level, + int optname, char __user *optval, int optlen); + int (*compat_getsockopt)(struct socket *sock, int level, + int optname, char __user *optval, int __user *optlen); int (*sendmsg) (struct kiocb *iocb, struct socket *sock, struct msghdr *m, size_t total_len); int (*recvmsg) (struct kiocb *iocb, struct socket *sock, diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h index 4688969398..412e52ca97 100644 --- a/include/linux/netfilter.h +++ b/include/linux/netfilter.h @@ -80,10 +80,14 @@ struct nf_sockopt_ops int set_optmin; int set_optmax; int (*set)(struct sock *sk, int optval, void __user *user, unsigned int len); + int (*compat_set)(struct sock *sk, int optval, + void __user *user, unsigned int len); int get_optmin; int get_optmax; int (*get)(struct sock *sk, int optval, void __user *user, int *len); + int (*compat_get)(struct sock *sk, int optval, + void __user *user, int *len); /* Number of users inside set() or get(). */ unsigned int use; @@ -246,6 +250,11 @@ int nf_setsockopt(struct sock *sk, int pf, int optval, char __user *opt, int nf_getsockopt(struct sock *sk, int pf, int optval, char __user *opt, int *len); +int compat_nf_setsockopt(struct sock *sk, int pf, int optval, + char __user *opt, int len); +int compat_nf_getsockopt(struct sock *sk, int pf, int optval, + char __user *opt, int *len); + /* Packet queuing */ struct nf_queue_handler { int (*outfn)(struct sk_buff *skb, struct nf_info *info, diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h index 363a067403..ae61331366 100644 --- a/include/net/inet_connection_sock.h +++ b/include/net/inet_connection_sock.h @@ -50,6 +50,12 @@ struct inet_connection_sock_af_ops { char __user *optval, int optlen); int (*getsockopt)(struct sock *sk, int level, int optname, char __user *optval, int __user *optlen); + int (*compat_setsockopt)(struct sock *sk, + int level, int optname, + char __user *optval, int optlen); + int (*compat_getsockopt)(struct sock *sk, + int level, int optname, + char __user *optval, int __user *optlen); void (*addr2sockaddr)(struct sock *sk, struct sockaddr *); int sockaddr_len; }; diff --git a/include/net/ip.h b/include/net/ip.h index fab3d5b3ab..8fe6156ca9 100644 --- a/include/net/ip.h +++ b/include/net/ip.h @@ -356,6 +356,10 @@ extern void ip_cmsg_recv(struct msghdr *msg, struct sk_buff *skb); extern int ip_cmsg_send(struct msghdr *msg, struct ipcm_cookie *ipc); extern int ip_setsockopt(struct sock *sk, int level, int optname, char __user *optval, int optlen); extern int ip_getsockopt(struct sock *sk, int level, int optname, char __user *optval, int __user *optlen); +extern int compat_ip_setsockopt(struct sock *sk, int level, + int optname, char __user *optval, int optlen); +extern int compat_ip_getsockopt(struct sock *sk, int level, + int optname, char __user *optval, int __user *optlen); extern int ip_ra_control(struct sock *sk, unsigned char on, void (*destructor)(struct sock *)); extern int ip_recv_error(struct sock *sk, struct msghdr *msg, int len); diff --git a/include/net/ipv6.h b/include/net/ipv6.h index c893a1ce4b..6d6f0634ae 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h @@ -520,6 +520,16 @@ extern int ipv6_getsockopt(struct sock *sk, int level, int optname, char __user *optval, int __user *optlen); +extern int compat_ipv6_setsockopt(struct sock *sk, + int level, + int optname, + char __user *optval, + int optlen); +extern int compat_ipv6_getsockopt(struct sock *sk, + int level, + int optname, + char __user *optval, + int __user *optlen); extern void ipv6_packet_init(void); diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index 072f407848..eba99f3755 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h @@ -514,6 +514,16 @@ struct sctp_af { int optname, char __user *optval, int __user *optlen); + int (*compat_setsockopt) (struct sock *sk, + int level, + int optname, + char __user *optval, + int optlen); + int (*compat_getsockopt) (struct sock *sk, + int level, + int optname, + char __user *optval, + int __user *optlen); struct dst_entry *(*get_dst) (struct sctp_association *asoc, union sctp_addr *daddr, union sctp_addr *saddr); diff --git a/include/net/sock.h b/include/net/sock.h index f63d0d5671..ec226f31dc 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -520,6 +520,14 @@ struct proto { int (*getsockopt)(struct sock *sk, int level, int optname, char __user *optval, int __user *option); + int (*compat_setsockopt)(struct sock *sk, + int level, + int optname, char __user *optval, + int optlen); + int (*compat_getsockopt)(struct sock *sk, + int level, + int optname, char __user *optval, + int __user *option); int (*sendmsg)(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, size_t len); int (*recvmsg)(struct kiocb *iocb, struct sock *sk, @@ -816,6 +824,10 @@ extern int sock_common_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t size, int flags); extern int sock_common_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int optlen); +extern int compat_sock_common_getsockopt(struct socket *sock, int level, + int optname, char __user *optval, int __user *optlen); +extern int compat_sock_common_setsockopt(struct socket *sock, int level, + int optname, char __user *optval, int optlen); extern void sk_common_release(struct sock *sk); diff --git a/include/net/tcp.h b/include/net/tcp.h index 457e224de4..9418f4d1af 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -353,6 +353,12 @@ extern int tcp_getsockopt(struct sock *sk, int level, extern int tcp_setsockopt(struct sock *sk, int level, int optname, char __user *optval, int optlen); +extern int compat_tcp_getsockopt(struct sock *sk, + int level, int optname, + char __user *optval, int __user *optlen); +extern int compat_tcp_setsockopt(struct sock *sk, + int level, int optname, + char __user *optval, int optlen); extern void tcp_set_keepalive(struct sock *sk, int val); extern int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, -- cgit v1.2.2 From dec73ff0293d59076d1fd8f4a264898ecfc457ec Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 20 Mar 2006 22:46:16 -0800 Subject: [ICSK] compat: Introduce inet_csk_compat_[gs]etsockopt Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: David S. Miller --- include/net/inet_connection_sock.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include') diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h index ae61331366..9bf73fe509 100644 --- a/include/net/inet_connection_sock.h +++ b/include/net/inet_connection_sock.h @@ -331,4 +331,9 @@ extern int inet_csk_ctl_sock_create(struct socket **sock, unsigned short family, unsigned short type, unsigned char protocol); + +extern int inet_csk_compat_getsockopt(struct sock *sk, int level, int optname, + char __user *optval, int __user *optlen); +extern int inet_csk_compat_setsockopt(struct sock *sk, int level, int optname, + char __user *optval, int optlen); #endif /* _INET_CONNECTION_SOCK_H */ -- cgit v1.2.2 From a4bf3902427a128455b8de299ff0918072b2e974 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 20 Mar 2006 22:50:58 -0800 Subject: [DCCP] minisock: Rename struct dccp_options to struct dccp_minisock This will later be included in struct dccp_request_sock so that we can have per connection feature negotiation state while in the 3way handshake, when we clone the DCCP_ROLE_LISTEN socket (in dccp_create_openreq_child) we'll just copy this state from dreq_minisock to dccps_minisock. Also the feature negotiation and option parsing code will mostly touch dccps_minisock, which will simplify some stuff. Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: David S. Miller --- include/linux/dccp.h | 43 ++++++++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 17 deletions(-) (limited to 'include') diff --git a/include/linux/dccp.h b/include/linux/dccp.h index e35f680f90..676333b9fa 100644 --- a/include/linux/dccp.h +++ b/include/linux/dccp.h @@ -328,21 +328,24 @@ static inline unsigned int dccp_hdr_len(const struct sk_buff *skb) #define DCCP_NDP_LIMIT 0xFFFFFF /** - * struct dccp_options - option values for a DCCP connection - * @dccpo_sequence_window - Sequence Window Feature (section 7.5.2) - * @dccpo_ccid - Congestion Control Id (CCID) (section 10) - * @dccpo_send_ack_vector - Send Ack Vector Feature (section 11.5) - * @dccpo_send_ndp_count - Send NDP Count Feature (7.7.2) + * struct dccp_minisock - Minimal DCCP connection representation + * + * Will be used to pass the state from dccp_request_sock to dccp_sock. + * + * @dccpms_sequence_window - Sequence Window Feature (section 7.5.2) + * @dccpms_ccid - Congestion Control Id (CCID) (section 10) + * @dccpms_send_ack_vector - Send Ack Vector Feature (section 11.5) + * @dccpms_send_ndp_count - Send NDP Count Feature (7.7.2) */ -struct dccp_options { - __u64 dccpo_sequence_window; - __u8 dccpo_rx_ccid; - __u8 dccpo_tx_ccid; - __u8 dccpo_send_ack_vector; - __u8 dccpo_send_ndp_count; - __u8 dccpo_ack_ratio; - struct list_head dccpo_pending; - struct list_head dccpo_conf; +struct dccp_minisock { + __u64 dccpms_sequence_window; + __u8 dccpms_rx_ccid; + __u8 dccpms_tx_ccid; + __u8 dccpms_send_ack_vector; + __u8 dccpms_send_ndp_count; + __u8 dccpms_ack_ratio; + struct list_head dccpms_pending; + struct list_head dccpms_conf; }; struct dccp_opt_conf { @@ -360,8 +363,9 @@ struct dccp_opt_pend { struct dccp_opt_conf *dccpop_sc; }; -extern void __dccp_options_init(struct dccp_options *dccpo); -extern void dccp_options_init(struct dccp_options *dccpo); +extern void __dccp_minisock_init(struct dccp_minisock *dmsk); +extern void dccp_minisock_init(struct dccp_minisock *dmsk); + extern int dccp_parse_options(struct sock *sk, struct sk_buff *skb); struct dccp_request_sock { @@ -457,7 +461,7 @@ struct dccp_sock { __u16 dccps_r_ack_ratio; unsigned long dccps_ndp_count; __u32 dccps_mss_cache; - struct dccp_options dccps_options; + struct dccp_minisock dccps_minisock; struct dccp_ackvec *dccps_hc_rx_ackvec; struct ccid *dccps_hc_rx_ccid; struct ccid *dccps_hc_tx_ccid; @@ -473,6 +477,11 @@ static inline struct dccp_sock *dccp_sk(const struct sock *sk) return (struct dccp_sock *)sk; } +static inline struct dccp_minisock *dccp_msk(const struct sock *sk) +{ + return (struct dccp_minisock *)&dccp_sk(sk)->dccps_minisock; +} + static inline int dccp_service_not_initialized(const struct sock *sk) { return dccp_sk(sk)->dccps_service == DCCP_SERVICE_INVALID_VALUE; -- cgit v1.2.2 From c8b2a6c50cacc98c924233a9e474c74c0370b6b8 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 20 Mar 2006 22:53:42 -0800 Subject: [SPARC]: Fixup SO_PEERSEC value on 32-bit sparc. Sparc64 and Sparc32 have to have identical socket call numbering in order to handle compat layer stuff properly. Signed-off-by: David S. Miller --- include/asm-sparc/socket.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/asm-sparc/socket.h b/include/asm-sparc/socket.h index 09575b608a..4e0ce3a35e 100644 --- a/include/asm-sparc/socket.h +++ b/include/asm-sparc/socket.h @@ -47,7 +47,7 @@ #define SO_TIMESTAMP 0x001d #define SCM_TIMESTAMP SO_TIMESTAMP -#define SO_PEERSEC 0x100e +#define SO_PEERSEC 0x001e /* Security levels - as per NRL IPv6 - don't actually do anything */ #define SO_SECURITY_AUTHENTICATION 0x5001 -- cgit v1.2.2 From fdeabdefb227be9aa932f59a23ddb47e003e643e Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 20 Mar 2006 22:58:21 -0800 Subject: [BRIDGE]: netfilter inline cleanup Move nf_bridge_alloc from header file to the one place it is used and optimize it. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- include/linux/netfilter_bridge.h | 27 --------------------------- 1 file changed, 27 deletions(-) (limited to 'include') diff --git a/include/linux/netfilter_bridge.h b/include/linux/netfilter_bridge.h index de4d397865..a75b84bb9a 100644 --- a/include/linux/netfilter_bridge.h +++ b/include/linux/netfilter_bridge.h @@ -47,22 +47,6 @@ enum nf_br_hook_priorities { #define BRNF_BRIDGED 0x08 #define BRNF_NF_BRIDGE_PREROUTING 0x10 -static inline -struct nf_bridge_info *nf_bridge_alloc(struct sk_buff *skb) -{ - struct nf_bridge_info **nf_bridge = &(skb->nf_bridge); - - if ((*nf_bridge = kmalloc(sizeof(**nf_bridge), GFP_ATOMIC)) != NULL) { - atomic_set(&(*nf_bridge)->use, 1); - (*nf_bridge)->mask = 0; - (*nf_bridge)->physindev = (*nf_bridge)->physoutdev = NULL; -#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) - (*nf_bridge)->netoutdev = NULL; -#endif - } - - return *nf_bridge; -} /* Only used in br_forward.c */ static inline @@ -77,17 +61,6 @@ void nf_bridge_maybe_copy_header(struct sk_buff *skb) } } -static inline -void nf_bridge_save_header(struct sk_buff *skb) -{ - int header_size = 16; - - if (skb->protocol == __constant_htons(ETH_P_8021Q)) - header_size = 18; - - memcpy(skb->nf_bridge->data, skb->data - header_size, header_size); -} - /* This is called by the IP fragmenting code and it ensures there is * enough room for the encapsulating header (if there is one). */ static inline -- cgit v1.2.2 From f4ad2b162d653e4a6e57d598119e3820c65fef71 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 20 Mar 2006 22:59:36 -0800 Subject: [LLC]: llc_mac_hdr_init const arguments Cleanup of LLC. llc_mac_hdr_init can take constant arguments, and it is defined twice once in llc_output.h that is otherwise unused. Signed-off-by: Stephen Hemminger Acked-by: Arnaldo Carvalho de Melo Signed-off-by: David S. Miller --- include/net/llc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/net/llc.h b/include/net/llc.h index 1adb2ef3f6..f5024583fc 100644 --- a/include/net/llc.h +++ b/include/net/llc.h @@ -71,7 +71,7 @@ extern int llc_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev); extern int llc_mac_hdr_init(struct sk_buff *skb, - unsigned char *sa, unsigned char *da); + const unsigned char *sa, const unsigned char *da); extern void llc_add_pack(int type, void (*handler)(struct llc_sap *sap, struct sk_buff *skb)); -- cgit v1.2.2 From 5e35941d990123f155b02d5663e51a24f816b6f3 Mon Sep 17 00:00:00 2001 From: Jing Min Zhao Date: Mon, 20 Mar 2006 23:41:17 -0800 Subject: [NETFILTER]: Add H.323 conntrack/NAT helper Signed-off-by: Jing Min Zhao Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- include/linux/netfilter_ipv4/ip_conntrack.h | 2 ++ include/linux/netfilter_ipv4/ip_conntrack_h323.h | 30 ++++++++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 include/linux/netfilter_ipv4/ip_conntrack_h323.h (limited to 'include') diff --git a/include/linux/netfilter_ipv4/ip_conntrack.h b/include/linux/netfilter_ipv4/ip_conntrack.h index 215765f043..f32d75c4f4 100644 --- a/include/linux/netfilter_ipv4/ip_conntrack.h +++ b/include/linux/netfilter_ipv4/ip_conntrack.h @@ -29,6 +29,7 @@ union ip_conntrack_expect_proto { }; /* Add protocol helper include file here */ +#include #include #include #include @@ -37,6 +38,7 @@ union ip_conntrack_expect_proto { /* per conntrack: application helper private data */ union ip_conntrack_help { /* insert conntrack helper private data (master) here */ + struct ip_ct_h323_master ct_h323_info; struct ip_ct_pptp_master ct_pptp_info; struct ip_ct_ftp_master ct_ftp_info; struct ip_ct_irc_master ct_irc_info; diff --git a/include/linux/netfilter_ipv4/ip_conntrack_h323.h b/include/linux/netfilter_ipv4/ip_conntrack_h323.h new file mode 100644 index 0000000000..0987cea538 --- /dev/null +++ b/include/linux/netfilter_ipv4/ip_conntrack_h323.h @@ -0,0 +1,30 @@ +#ifndef _IP_CONNTRACK_H323_H +#define _IP_CONNTRACK_H323_H + +#ifdef __KERNEL__ + +#define RAS_PORT 1719 +#define Q931_PORT 1720 +#define H323_RTP_CHANNEL_MAX 4 /* Audio, video, FAX and other */ + +/* This structure exists only once per master */ +struct ip_ct_h323_master { + + /* Original and NATed Q.931 or H.245 signal ports */ + u_int16_t sig_port[IP_CT_DIR_MAX]; + + /* Original and NATed RTP ports */ + u_int16_t rtp_port[H323_RTP_CHANNEL_MAX][IP_CT_DIR_MAX]; + + union { + /* RAS connection timeout */ + u_int32_t timeout; + + /* Next TPKT length (for separate TPKT header and data) */ + u_int16_t tpkt_len[IP_CT_DIR_MAX]; + }; +}; + +#endif + +#endif -- cgit v1.2.2 From f10b7897ee29649fa7f0ccdc8d859ccd6ce7dbfd Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Wed, 25 Jan 2006 22:34:01 +1100 Subject: [CRYPTO] api: Align tfm context as wide as possible Since tfm contexts can contain arbitrary types we should provide at least natural alignment (__attribute__ ((__aligned__))) for them. In particular, this is needed on the Xscale which is a 32-bit architecture with a u64 type that requires 64-bit alignment. This problem was reported by Ronen Shitrit. The crypto_tfm structure's size was 44 bytes on 32-bit architectures and 80 bytes on 64-bit architectures. So adding this requirement only means that we have to add an extra 4 bytes on 32-bit architectures. On i386 the natural alignment is 16 bytes which also benefits the VIA Padlock as it no longer has to manually align its context structure to 128 bits. Signed-off-by: Herbert Xu --- include/linux/crypto.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/crypto.h b/include/linux/crypto.h index d88bf8aa8b..0ab1bc1152 100644 --- a/include/linux/crypto.h +++ b/include/linux/crypto.h @@ -229,6 +229,8 @@ struct crypto_tfm { } crt_u; struct crypto_alg *__crt_alg; + + char __crt_ctx[] __attribute__ ((__aligned__)); }; /* @@ -301,7 +303,13 @@ static inline unsigned int crypto_tfm_alg_alignmask(struct crypto_tfm *tfm) static inline void *crypto_tfm_ctx(struct crypto_tfm *tfm) { - return (void *)&tfm[1]; + return tfm->__crt_ctx; +} + +static inline unsigned int crypto_tfm_ctx_alignment(void) +{ + struct crypto_tfm *tfm; + return __alignof__(tfm->__crt_ctx); } /* -- cgit v1.2.2 From e87dddeb92618d9dbb8b9f946a193739a4447609 Mon Sep 17 00:00:00 2001 From: Peter Horton Date: Sun, 12 Feb 2006 17:10:25 +0000 Subject: [MIPS] Add early console for Cobalt. Signed-off-by: Peter Horton Signed-off-by: Ralf Baechle --- include/asm-mips/mach-cobalt/cobalt.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/asm-mips/mach-cobalt/cobalt.h b/include/asm-mips/mach-cobalt/cobalt.h index 78e1df2095..b3c5ecbec0 100644 --- a/include/asm-mips/mach-cobalt/cobalt.h +++ b/include/asm-mips/mach-cobalt/cobalt.h @@ -113,4 +113,6 @@ do { \ # define COBALT_KEY_SELECT (1 << 7) # define COBALT_KEY_MASK 0xfe +#define COBALT_UART ((volatile unsigned char *) CKSEG1ADDR(0x1c800000)) + #endif /* __ASM_COBALT_H */ -- cgit v1.2.2 From bbad8123f3a40a7b262e8e52d0bc10da67d719bb Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Wed, 15 Feb 2006 13:06:34 +0000 Subject: [MIPS] MIPS64 R2 optimizations for 64-bit endianess swapping. Signed-off-by: Ralf Baechle --- include/asm-mips/byteorder.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'include') diff --git a/include/asm-mips/byteorder.h b/include/asm-mips/byteorder.h index 584f8128ff..aefc02f16f 100644 --- a/include/asm-mips/byteorder.h +++ b/include/asm-mips/byteorder.h @@ -39,6 +39,24 @@ static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 x) } #define __arch__swab32(x) ___arch__swab32(x) +#ifdef CONFIG_CPU_MIPS64_R2 + +static __inline__ __attribute_const__ __u64 ___arch__swab64(__u64 x) +{ + __asm__( + " dsbh %0, %1 \n" + " dshd %0, %0 \n" + " drotr %0, %0, 32 \n" + : "=r" (x) + : "r" (x)); + + return x; +} + +#define __arch__swab64(x) ___arch__swab64(x) + +#endif /* CONFIG_CPU_MIPS64_R2 */ + #endif /* CONFIG_CPU_MIPSR2 */ #if !defined(__STRICT_ANSI__) || defined(__KERNEL__) -- cgit v1.2.2 From 37caa934af02bc01d0e1366a49e1c89360fa0f29 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Wed, 15 Feb 2006 18:25:48 +0900 Subject: [MIPS] sc-rm7k.c cleanup Use blast_scache_range, blast_inv_scache_range for rm7k scache routine. Output code should be logically same. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- include/asm-mips/r4kcache.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/asm-mips/r4kcache.h b/include/asm-mips/r4kcache.h index 0bcb79a58e..90c3747009 100644 --- a/include/asm-mips/r4kcache.h +++ b/include/asm-mips/r4kcache.h @@ -303,5 +303,6 @@ __BUILD_BLAST_CACHE_RANGE(d, dcache, Hit_Writeback_Inv_D, ) __BUILD_BLAST_CACHE_RANGE(s, scache, Hit_Writeback_Inv_SD, ) /* blast_inv_dcache_range */ __BUILD_BLAST_CACHE_RANGE(inv_d, dcache, Hit_Invalidate_D, ) +__BUILD_BLAST_CACHE_RANGE(inv_s, scache, Hit_Invalidate_SD, ) #endif /* _ASM_R4KCACHE_H */ -- cgit v1.2.2 From a8433137ea9143bb3a2bc18a3407b5a130fdb868 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Fri, 17 Feb 2006 01:36:24 +0900 Subject: [MIPS] Make I/O helpers more customizable 1. Move ioswab*() and __mem_ioswab*() to mangle-port.h. This gets rid of CONFIG_SGI_IP22 from include/asm-mips/io.h. 2. Pass a virtual address to *ioswab*(). Then we can provide mach-specific *ioswab*() and can do every evil thing based on its argument. It could be useful on machines which have regions with different endian conversion scheme. 3. Call __swizzle_addr*() _after_ adding mips_io_port_base. This unifies the meaning of the argument of __swizzle_addr*() (always virtual address). Then mach-specific __swizzle_addr*() can do every evil thing based on the argument. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- include/asm-mips/io.h | 69 +++++------------------------ include/asm-mips/mach-generic/mangle-port.h | 36 +++++++++++++++ include/asm-mips/mach-ip27/mangle-port.h | 9 ++++ include/asm-mips/mach-ip32/mangle-port.h | 9 ++++ 4 files changed, 66 insertions(+), 57 deletions(-) (limited to 'include') diff --git a/include/asm-mips/io.h b/include/asm-mips/io.h index ba1d7bbc15..546a17e56a 100644 --- a/include/asm-mips/io.h +++ b/include/asm-mips/io.h @@ -40,56 +40,13 @@ * hardware. An example use would be for flash memory that's used for * execute in place. */ -# define __raw_ioswabb(x) (x) -# define __raw_ioswabw(x) (x) -# define __raw_ioswabl(x) (x) -# define __raw_ioswabq(x) (x) -# define ____raw_ioswabq(x) (x) +# define __raw_ioswabb(a,x) (x) +# define __raw_ioswabw(a,x) (x) +# define __raw_ioswabl(a,x) (x) +# define __raw_ioswabq(a,x) (x) +# define ____raw_ioswabq(a,x) (x) -/* - * Sane hardware offers swapping of PCI/ISA I/O space accesses in hardware; - * less sane hardware forces software to fiddle with this... - * - * Regardless, if the host bus endianness mismatches that of PCI/ISA, then - * you can't have the numerical value of data and byte addresses within - * multibyte quantities both preserved at the same time. Hence two - * variations of functions: non-prefixed ones that preserve the value - * and prefixed ones that preserve byte addresses. The latters are - * typically used for moving raw data between a peripheral and memory (cf. - * string I/O functions), hence the "__mem_" prefix. - */ -#if defined(CONFIG_SWAP_IO_SPACE) - -# define ioswabb(x) (x) -# define __mem_ioswabb(x) (x) -# ifdef CONFIG_SGI_IP22 -/* - * IP22 seems braindead enough to swap 16bits values in hardware, but - * not 32bits. Go figure... Can't tell without documentation. - */ -# define ioswabw(x) (x) -# define __mem_ioswabw(x) le16_to_cpu(x) -# else -# define ioswabw(x) le16_to_cpu(x) -# define __mem_ioswabw(x) (x) -# endif -# define ioswabl(x) le32_to_cpu(x) -# define __mem_ioswabl(x) (x) -# define ioswabq(x) le64_to_cpu(x) -# define __mem_ioswabq(x) (x) - -#else - -# define ioswabb(x) (x) -# define __mem_ioswabb(x) (x) -# define ioswabw(x) (x) -# define __mem_ioswabw(x) cpu_to_le16(x) -# define ioswabl(x) (x) -# define __mem_ioswabl(x) cpu_to_le32(x) -# define ioswabq(x) (x) -# define __mem_ioswabq(x) cpu_to_le32(x) - -#endif +/* ioswab[bwlq], __mem_ioswab[bwlq] are defined in mangle-port.h */ #define IO_SPACE_LIMIT 0xffff @@ -346,7 +303,7 @@ static inline void pfx##write##bwlq(type val, \ \ __mem = (void *)__swizzle_addr_##bwlq((unsigned long)(mem)); \ \ - __val = pfx##ioswab##bwlq(val); \ + __val = pfx##ioswab##bwlq(__mem, val); \ \ if (sizeof(type) != sizeof(u64) || sizeof(u64) == sizeof(long)) \ *__mem = __val; \ @@ -401,7 +358,7 @@ static inline type pfx##read##bwlq(const volatile void __iomem *mem) \ BUG(); \ } \ \ - return pfx##ioswab##bwlq(__val); \ + return pfx##ioswab##bwlq(__mem, __val); \ } #define __BUILD_IOPORT_SINGLE(pfx, bwlq, type, p, slow) \ @@ -411,10 +368,9 @@ static inline void pfx##out##bwlq##p(type val, unsigned long port) \ volatile type *__addr; \ type __val; \ \ - port = __swizzle_addr_##bwlq(port); \ - __addr = (void *)(mips_io_port_base + port); \ + __addr = (void *)__swizzle_addr_##bwlq(mips_io_port_base + port); \ \ - __val = pfx##ioswab##bwlq(val); \ + __val = pfx##ioswab##bwlq(__addr, val); \ \ /* Really, we want this to be atomic */ \ BUILD_BUG_ON(sizeof(type) > sizeof(unsigned long)); \ @@ -428,15 +384,14 @@ static inline type pfx##in##bwlq##p(unsigned long port) \ volatile type *__addr; \ type __val; \ \ - port = __swizzle_addr_##bwlq(port); \ - __addr = (void *)(mips_io_port_base + port); \ + __addr = (void *)__swizzle_addr_##bwlq(mips_io_port_base + port); \ \ BUILD_BUG_ON(sizeof(type) > sizeof(unsigned long)); \ \ __val = *__addr; \ slow; \ \ - return pfx##ioswab##bwlq(__val); \ + return pfx##ioswab##bwlq(__addr, __val); \ } #define __BUILD_MEMORY_PFX(bus, bwlq, type) \ diff --git a/include/asm-mips/mach-generic/mangle-port.h b/include/asm-mips/mach-generic/mangle-port.h index 4a98d83b8e..6e1b0c075d 100644 --- a/include/asm-mips/mach-generic/mangle-port.h +++ b/include/asm-mips/mach-generic/mangle-port.h @@ -13,4 +13,40 @@ #define __swizzle_addr_l(port) (port) #define __swizzle_addr_q(port) (port) +/* + * Sane hardware offers swapping of PCI/ISA I/O space accesses in hardware; + * less sane hardware forces software to fiddle with this... + * + * Regardless, if the host bus endianness mismatches that of PCI/ISA, then + * you can't have the numerical value of data and byte addresses within + * multibyte quantities both preserved at the same time. Hence two + * variations of functions: non-prefixed ones that preserve the value + * and prefixed ones that preserve byte addresses. The latters are + * typically used for moving raw data between a peripheral and memory (cf. + * string I/O functions), hence the "__mem_" prefix. + */ +#if defined(CONFIG_SWAP_IO_SPACE) + +# define ioswabb(a,x) (x) +# define __mem_ioswabb(a,x) (x) +# define ioswabw(a,x) le16_to_cpu(x) +# define __mem_ioswabw(a,x) (x) +# define ioswabl(a,x) le32_to_cpu(x) +# define __mem_ioswabl(a,x) (x) +# define ioswabq(a,x) le64_to_cpu(x) +# define __mem_ioswabq(a,x) (x) + +#else + +# define ioswabb(a,x) (x) +# define __mem_ioswabb(a,x) (x) +# define ioswabw(a,x) (x) +# define __mem_ioswabw(a,x) cpu_to_le16(x) +# define ioswabl(a,x) (x) +# define __mem_ioswabl(a,x) cpu_to_le32(x) +# define ioswabq(a,x) (x) +# define __mem_ioswabq(a,x) cpu_to_le32(x) + +#endif + #endif /* __ASM_MACH_GENERIC_MANGLE_PORT_H */ diff --git a/include/asm-mips/mach-ip27/mangle-port.h b/include/asm-mips/mach-ip27/mangle-port.h index f76c448804..d615312a45 100644 --- a/include/asm-mips/mach-ip27/mangle-port.h +++ b/include/asm-mips/mach-ip27/mangle-port.h @@ -13,4 +13,13 @@ #define __swizzle_addr_l(port) (port) #define __swizzle_addr_q(port) (port) +# define ioswabb(a,x) (x) +# define __mem_ioswabb(a,x) (x) +# define ioswabw(a,x) (x) +# define __mem_ioswabw(a,x) cpu_to_le16(x) +# define ioswabl(a,x) (x) +# define __mem_ioswabl(a,x) cpu_to_le32(x) +# define ioswabq(a,x) (x) +# define __mem_ioswabq(a,x) cpu_to_le32(x) + #endif /* __ASM_MACH_IP27_MANGLE_PORT_H */ diff --git a/include/asm-mips/mach-ip32/mangle-port.h b/include/asm-mips/mach-ip32/mangle-port.h index 6e25b52ed8..81320eb553 100644 --- a/include/asm-mips/mach-ip32/mangle-port.h +++ b/include/asm-mips/mach-ip32/mangle-port.h @@ -14,4 +14,13 @@ #define __swizzle_addr_l(port) (port) #define __swizzle_addr_q(port) (port) +# define ioswabb(a,x) (x) +# define __mem_ioswabb(a,x) (x) +# define ioswabw(a,x) (x) +# define __mem_ioswabw(a,x) cpu_to_le16(x) +# define ioswabl(a,x) (x) +# define __mem_ioswabl(a,x) cpu_to_le32(x) +# define ioswabq(a,x) (x) +# define __mem_ioswabq(a,x) cpu_to_le32(x) + #endif /* __ASM_MACH_IP32_MANGLE_PORT_H */ -- cgit v1.2.2 From 9c6031cc93626a194a9ef32d62b078ef1b396c45 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Sun, 19 Feb 2006 23:46:44 +0900 Subject: [MIPS] Signal cleanup Move function prototypes to asm/signal.h to detect trivial errors and add some __user tags to get rid of sparse warnings. Generated code should not be changed. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- include/asm-mips/signal.h | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/asm-mips/signal.h b/include/asm-mips/signal.h index 6fe903e09c..d8349e4b55 100644 --- a/include/asm-mips/signal.h +++ b/include/asm-mips/signal.h @@ -147,16 +147,34 @@ struct k_sigaction { /* IRIX compatible stack_t */ typedef struct sigaltstack { - void *ss_sp; + void __user *ss_sp; size_t ss_size; int ss_flags; } stack_t; #ifdef __KERNEL__ #include +#include #define ptrace_signal_deliver(regs, cookie) do { } while (0) +struct pt_regs; +extern void do_signal(struct pt_regs *regs); +extern void do_signal32(struct pt_regs *regs); + +extern int setup_frame(struct k_sigaction * ka, struct pt_regs *regs, + int signr, sigset_t *set); +extern int setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs, + int signr, sigset_t *set, siginfo_t *info); + +extern int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs, + int signr, sigset_t *set); +extern int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs, + int signr, sigset_t *set, siginfo_t *info); + +extern int setup_rt_frame_n32(struct k_sigaction * ka, struct pt_regs *regs, + int signr, sigset_t *set, siginfo_t *info); + #endif /* __KERNEL__ */ #endif /* _ASM_SIGNAL_H */ -- cgit v1.2.2 From 219ac73a7ad17a3ae3d5c07b4fc8c280645a073a Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Tue, 21 Feb 2006 16:05:11 +0900 Subject: [MIPS] Further sparsification for 32-bit compat code. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- include/asm-mips/compat.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/asm-mips/compat.h b/include/asm-mips/compat.h index 35d2604fe6..0012bd804d 100644 --- a/include/asm-mips/compat.h +++ b/include/asm-mips/compat.h @@ -128,17 +128,17 @@ typedef u32 compat_sigset_word; */ typedef u32 compat_uptr_t; -static inline void *compat_ptr(compat_uptr_t uptr) +static inline void __user *compat_ptr(compat_uptr_t uptr) { - return (void *)(long)uptr; + return (void __user *)(long)uptr; } -static inline void *compat_alloc_user_space(long len) +static inline void __user *compat_alloc_user_space(long len) { struct pt_regs *regs = (struct pt_regs *) ((unsigned long) current_thread_info() + THREAD_SIZE - 32) - 1; - return (void *) (regs->regs[29] - len); + return (void __user *) (regs->regs[29] - len); } #if defined (__MIPSEL__) #define __COMPAT_ENDIAN_SWAP__ 1 -- cgit v1.2.2 From 8145095cd8fd466980ea6401f26a52e462275222 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Wed, 22 Feb 2006 23:06:55 +0000 Subject: [MIPS] Remove CONFIG_BUILD_ELF64. This option is no longer usable with supported compilers. It will be replaced by usage of -msym32 in a separate patch. Signed-off-by: Ralf Baechle --- include/asm-mips/mmu_context.h | 7 +------ include/asm-mips/sn/mapped_kernel.h | 4 ---- include/asm-mips/stackframe.h | 20 +++----------------- 3 files changed, 4 insertions(+), 27 deletions(-) (limited to 'include') diff --git a/include/asm-mips/mmu_context.h b/include/asm-mips/mmu_context.h index 19cdf7642e..61cf225881 100644 --- a/include/asm-mips/mmu_context.h +++ b/include/asm-mips/mmu_context.h @@ -33,12 +33,7 @@ extern unsigned long pgd_current[]; write_c0_context((unsigned long) smp_processor_id() << 25); \ TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir) #endif -#if defined(CONFIG_64BIT) && !defined(CONFIG_BUILD_ELF64) -#define TLBMISS_HANDLER_SETUP() \ - write_c0_context((unsigned long) &pgd_current[smp_processor_id()] << 23); \ - TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir) -#endif -#if defined(CONFIG_64BIT) && defined(CONFIG_BUILD_ELF64) +#ifdef CONFIG_64BIT #define TLBMISS_HANDLER_SETUP() \ write_c0_context((unsigned long) smp_processor_id() << 26); \ TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir) diff --git a/include/asm-mips/sn/mapped_kernel.h b/include/asm-mips/sn/mapped_kernel.h index 3a17846df8..59edb20f8e 100644 --- a/include/asm-mips/sn/mapped_kernel.h +++ b/include/asm-mips/sn/mapped_kernel.h @@ -23,11 +23,7 @@ #include #include -#ifdef CONFIG_BUILD_ELF64 #define REP_BASE CAC_BASE -#else -#define REP_BASE CKSEG0 -#endif #ifdef CONFIG_MAPPED_KERNEL diff --git a/include/asm-mips/stackframe.h b/include/asm-mips/stackframe.h index a8919dcc93..2acf3e844f 100644 --- a/include/asm-mips/stackframe.h +++ b/include/asm-mips/stackframe.h @@ -63,17 +63,7 @@ addu k1, k0 LONG_L k1, %lo(kernelsp)(k1) #endif -#if defined(CONFIG_64BIT) && !defined(CONFIG_BUILD_ELF64) - MFC0 k1, CP0_CONTEXT - dsra k1, 23 - lui k0, %hi(pgd_current) - addiu k0, %lo(pgd_current) - dsubu k1, k0 - lui k0, %hi(kernelsp) - daddu k1, k0 - LONG_L k1, %lo(kernelsp)(k1) -#endif -#if defined(CONFIG_64BIT) && defined(CONFIG_BUILD_ELF64) +#ifdef CONFIG_64BIT MFC0 k1, CP0_CONTEXT lui k0, %highest(kernelsp) dsrl k1, 23 @@ -91,11 +81,7 @@ mfc0 \temp, CP0_CONTEXT srl \temp, 23 #endif -#if defined(CONFIG_64BIT) && !defined(CONFIG_BUILD_ELF64) - lw \temp, TI_CPU(gp) - dsll \temp, 3 -#endif -#if defined(CONFIG_64BIT) && defined(CONFIG_BUILD_ELF64) +#ifdef CONFIG_64BIT MFC0 \temp, CP0_CONTEXT dsrl \temp, 23 #endif @@ -103,7 +89,7 @@ .endm #else .macro get_saved_sp /* Uniprocessor variation */ -#if defined(CONFIG_64BIT) && defined(CONFIG_BUILD_ELF64) +#ifdef CONFIG_64BIT lui k1, %highest(kernelsp) daddiu k1, %higher(kernelsp) dsll k1, k1, 16 -- cgit v1.2.2 From 0cea043b56443aef8a77539cdd79451f5d55009d Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Fri, 3 Mar 2006 09:42:05 +0000 Subject: [MIPS] Reformat __xchg(). Signed-off-by: Ralf Baechle --- include/asm-mips/system.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/asm-mips/system.h b/include/asm-mips/system.h index ddae9bae31..4097fac5ac 100644 --- a/include/asm-mips/system.h +++ b/include/asm-mips/system.h @@ -286,10 +286,10 @@ extern void __xchg_called_with_bad_pointer(void); static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size) { switch (size) { - case 4: - return __xchg_u32(ptr, x); - case 8: - return __xchg_u64(ptr, x); + case 4: + return __xchg_u32(ptr, x); + case 8: + return __xchg_u64(ptr, x); } __xchg_called_with_bad_pointer(); return x; -- cgit v1.2.2 From a3dddd560ee936495466d85ecc97490d171e8d31 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Sat, 11 Mar 2006 08:18:41 +0000 Subject: [MIPS] War on whitespace: cleanup initial spaces followed by tabs. Signed-off-by: Ralf Baechle --- include/asm-mips/pgtable-32.h | 2 +- include/asm-mips/sn/klconfig.h | 2 +- include/asm-mips/sn/sn0/hubio.h | 12 ++++++------ include/asm-mips/thread_info.h | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) (limited to 'include') diff --git a/include/asm-mips/pgtable-32.h b/include/asm-mips/pgtable-32.h index 0cff64ce0f..4d6bc45df5 100644 --- a/include/asm-mips/pgtable-32.h +++ b/include/asm-mips/pgtable-32.h @@ -206,7 +206,7 @@ pfn_pte(unsigned long pfn, pgprot_t prot) /* fixme */ #define pte_to_pgoff(_pte) (((_pte).pte_high >> 6) + ((_pte).pte_high & 0x3f)) #define pgoff_to_pte(off) \ - ((pte_t){(((off) & 0x3f) + ((off) << 6) + _PAGE_FILE)}) + ((pte_t){(((off) & 0x3f) + ((off) << 6) + _PAGE_FILE)}) #else #define pte_to_pgoff(_pte) \ diff --git a/include/asm-mips/sn/klconfig.h b/include/asm-mips/sn/klconfig.h index d028e28d62..9709ff701d 100644 --- a/include/asm-mips/sn/klconfig.h +++ b/include/asm-mips/sn/klconfig.h @@ -99,7 +99,7 @@ typedef s32 klconf_off_t; #define ENABLE_BOARD 0x01 #define FAILED_BOARD 0x02 #define DUPLICATE_BOARD 0x04 /* Boards like midplanes/routers which - are discovered twice. Use one of them */ + are discovered twice. Use one of them */ #define VISITED_BOARD 0x08 /* Used for compact hub numbering. */ #define LOCAL_MASTER_IO6 0x10 /* master io6 for that node */ #define GLOBAL_MASTER_IO6 0x20 diff --git a/include/asm-mips/sn/sn0/hubio.h b/include/asm-mips/sn/sn0/hubio.h index 80cf6a52ed..f314da21b9 100644 --- a/include/asm-mips/sn/sn0/hubio.h +++ b/include/asm-mips/sn/sn0/hubio.h @@ -229,7 +229,7 @@ typedef union hubii_ilcsr_u { icsr_llp_en: 1, /* LLP enable bit */ icsr_rsvd2: 1, /* reserver */ icsr_wrm_reset: 1, /* Warm reset bit */ - icsr_rsvd1: 2, /* Data ready offset */ + icsr_rsvd1: 2, /* Data ready offset */ icsr_null_to: 6; /* Null timeout */ } icsr_fields_s; @@ -274,9 +274,9 @@ typedef union io_perf_sel { u64 perf_sel_reg; struct { u64 perf_rsvd : 48, - perf_icct : 8, - perf_ippr1 : 4, - perf_ippr0 : 4; + perf_icct : 8, + perf_ippr1 : 4, + perf_ippr0 : 4; } perf_sel_bits; } io_perf_sel_t; @@ -287,8 +287,8 @@ typedef union io_perf_cnt { u64 perf_cnt; struct { u64 perf_rsvd1 : 32, - perf_rsvd2 : 12, - perf_cnt : 20; + perf_rsvd2 : 12, + perf_cnt : 20; } perf_cnt_bits; } io_perf_cnt_t; diff --git a/include/asm-mips/thread_info.h b/include/asm-mips/thread_info.h index fa193f861e..f8d97dafd2 100644 --- a/include/asm-mips/thread_info.h +++ b/include/asm-mips/thread_info.h @@ -31,7 +31,7 @@ struct thread_info { int preempt_count; /* 0 => preemptable, <0 => BUG */ mm_segment_t addr_limit; /* thread address space: - 0-0xBFFFFFFF for user-thead + 0-0xBFFFFFFF for user-thead 0-0xFFFFFFFF for kernel-thread */ struct restart_block restart_block; -- cgit v1.2.2 From f3629be8388a679590eb919919ee63e2715ec25e Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sat, 11 Mar 2006 17:02:01 -0300 Subject: V4L/DVB (3445): LG TALN series: add PAL / SECAM support - added tuner_lg_taln_pal_secam_ranges - renamed tuner 66 from TUNER_LG_NTSC_TALN_MINI to TUNER_LG_TALN - updated FlyTV mini Asus Digimatrix with new tuner Thanks-to: Rickard Osser Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- include/media/tuner.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/media/tuner.h b/include/media/tuner.h index 02d7d9a76f..017fed7d5e 100644 --- a/include/media/tuner.h +++ b/include/media/tuner.h @@ -110,7 +110,7 @@ #define TUNER_LG_TDVS_H062F 64 /* DViCO FusionHDTV 5 */ #define TUNER_YMEC_TVF66T5_B_DFF 65 /* Acorp Y878F */ -#define TUNER_LG_NTSC_TALN_MINI 66 +#define TUNER_LG_TALN 66 #define TUNER_PHILIPS_TD1316 67 #define TUNER_PHILIPS_TUV1236D 68 /* ATI HDTV Wonder */ -- cgit v1.2.2 From f5762e441d5022ecc5b66b5fe54e41e2ac5d02be Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 13 Mar 2006 13:31:31 -0300 Subject: V4L/DVB (3513): Remove saa711x driver Now, em28xx uses saa7115 instead of saa711x. saa7115 driver is capable of handling saa 7113, 7114 and 7115. Signed-off-by: Mauro Carvalho Chehab --- include/media/v4l2-common.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h index c44741e78f..2360453e74 100644 --- a/include/media/v4l2-common.h +++ b/include/media/v4l2-common.h @@ -103,6 +103,7 @@ enum v4l2_chip_ident { V4L2_IDENT_UNKNOWN = 0, /* module saa7115: reserved range 100-149 */ + V4L2_IDENT_SAA7113 = 103, V4L2_IDENT_SAA7114 = 104, V4L2_IDENT_SAA7115 = 105, -- cgit v1.2.2