Skip to contentSkip to conversation

can: c_can: fix invalid error codes

PATCH New Greg Kroah-Hartman 1 participant 15 messages Feb 1, 2013 1 message not in the archive

Subsystems (10)
Stable branch Arm (32-bit) x86 Sound +6 more subsystems
lore
Share & tools
lore

A message that is not in the archive (sent off-list or not yet received): [email protected]

Greg Kroah-Hartman

author maintainer
#1 lore raw

PATCH 1/15 can: c_can: fix invalid error codes

3.0-stable review patch. If anyone has any objections, please let me know.

------------------

From: Olivier Sobrie <[email protected]>

commit 6ea45886865c1abb01bb861f7f6bdd5d0f398cb3 upstream.

Errors in CAN protocol (location) are reported in data[3] of the can frame instead of data[2].

---
 drivers/net/can/c_can/c_can.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/can/c_can/c_can.c +2 -2
@@ -916,7 +916,7 @@ static int c_can_handle_bus_err(struct n
 		break;
 	case LEC_ACK_ERROR:
 		netdev_dbg(dev, "ack error\n");
-		cf->data[2] |= (CAN_ERR_PROT_LOC_ACK |
+		cf->data[3] |= (CAN_ERR_PROT_LOC_ACK |
 				CAN_ERR_PROT_LOC_ACK_DEL);
 		break;
 	case LEC_BIT1_ERROR:
@@ -929,7 +929,7 @@ static int c_can_handle_bus_err(struct n
 		break;
 	case LEC_CRC_ERROR:
 		netdev_dbg(dev, "CRC error\n");
-		cf->data[2] |= (CAN_ERR_PROT_LOC_CRC_SEQ |
+		cf->data[3] |= (CAN_ERR_PROT_LOC_CRC_SEQ |
 				CAN_ERR_PROT_LOC_CRC_DEL);
 		break;
 	default:
author maintainer
#2 lore raw

PATCH 2/15 can: ti_hecc: fix invalid error codes

In reply to a message not in the archive

3.0-stable review patch. If anyone has any objections, please let me know.

------------------

From: Olivier Sobrie <[email protected]>

commit 71088c4bd9b8f8cbffb0e66f2abc14297e4b2ca8 upstream.

Errors in CAN protocol (location) are reported in data[3] of the can frame instead of data[2].

---
 drivers/net/can/ti_hecc.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/can/ti_hecc.c +2 -2
@@ -734,12 +734,12 @@ static int ti_hecc_error(struct net_devi
 		}
 		if (err_status & HECC_CANES_CRCE) {
 			hecc_set_bit(priv, HECC_CANES, HECC_CANES_CRCE);
-			cf->data[2] |= CAN_ERR_PROT_LOC_CRC_SEQ |
+			cf->data[3] |= CAN_ERR_PROT_LOC_CRC_SEQ |
 					CAN_ERR_PROT_LOC_CRC_DEL;
 		}
 		if (err_status & HECC_CANES_ACKE) {
 			hecc_set_bit(priv, HECC_CANES, HECC_CANES_ACKE);
-			cf->data[2] |= CAN_ERR_PROT_LOC_ACK |
+			cf->data[3] |= CAN_ERR_PROT_LOC_ACK |
 					CAN_ERR_PROT_LOC_ACK_DEL;
 		}
 	}
author maintainer
#3 lore raw

PATCH 3/15 can: pch_can: fix invalid error codes

In reply to a message not in the archive

3.0-stable review patch. If anyone has any objections, please let me know.

------------------

From: Olivier Sobrie <[email protected]>

commit ee50e135aeb048b90fab662e661c58b67341830b upstream.

Errors in CAN protocol (location) are reported in data[3] of the can frame instead of data[2].

---
 drivers/net/can/pch_can.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/can/pch_can.c +1 -1
@@ -559,7 +559,7 @@ static void pch_can_error(struct net_dev
 		stats->rx_errors++;
 		break;
 	case PCH_CRC_ERR:
-		cf->data[2] |= CAN_ERR_PROT_LOC_CRC_SEQ |
+		cf->data[3] |= CAN_ERR_PROT_LOC_CRC_SEQ |
 			       CAN_ERR_PROT_LOC_CRC_DEL;
 		priv->can.can_stats.bus_error++;
 		stats->rx_errors++;
author maintainer
#4 lore raw

PATCH 4/15 fs/cifs/cifs_dfs_ref.c: fix potential memory leakage

In reply to a message not in the archive

3.0-stable review patch. If anyone has any objections, please let me know.

------------------

From: Cong Ding <[email protected]>

commit 10b8c7dff5d3633b69e77f57d404dab54ead3787 upstream.

When it goes to error through line 144, the memory allocated to *devname is not freed, and the caller doesn't free it either in line 250. So we free the memroy of *devname in function cifs_compose_mount_options() when it goes to error.

---
 fs/cifs/cifs_dfs_ref.c |    2 ++
 1 file changed, 2 insertions(+)
fs/cifs/cifs_dfs_ref.c +2 -0
@@ -225,6 +225,8 @@ compose_mount_options_out:
 compose_mount_options_err:
 	kfree(mountdata);
 	mountdata = ERR_PTR(rc);
+	kfree(*devname);
+	*devname = NULL;
 	goto compose_mount_options_out;
 }
 
author maintainer
#5 lore raw

PATCH 5/15 ARM: DMA: Fix struct page iterator in dma_cache_maint() to work with sparsemem

In reply to a message not in the archive

3.0-stable review patch. If anyone has any objections, please let me know.

------------------

From: Russell King <[email protected]>

commit 15653371c67c3fbe359ae37b720639dd4c7b42c5 upstream.

Subhash Jadavani reported this partial backtrace:
Now consider this call stack from MMC block driver (this is on the ARMv7 based board):

[<c001b50c>] (v7_dma_inv_range+0x30/0x48) from [<c0017b8c>] (dma_cache_maint_page+0x1c4/0x24c) [<c0017b8c>] (dma_cache_maint_page+0x1c4/0x24c) from [<c0017c28>] (___dma_page_cpu_to_dev+0x14/0x1c) [<c0017c28>] (___dma_page_cpu_to_dev+0x14/0x1c) from [<c0017ff8>] (dma_map_sg+0x3c/0x114)

This is caused by incrementing the struct page pointer, and running off the end of the sparsemem page array. Fix this by incrementing by pfn instead, and convert the pfn to a struct page.

---
 arch/arm/mm/dma-mapping.c |   18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)
arch/arm/mm/dma-mapping.c +10 -8
@@ -467,25 +467,27 @@ static void dma_cache_maint_page(struct
 	size_t size, enum dma_data_direction dir,
 	void (*op)(const void *, size_t, int))
 {
+	unsigned long pfn;
+	size_t left = size;
+
+	pfn = page_to_pfn(page) + offset / PAGE_SIZE;
+	offset %= PAGE_SIZE;
+
 	/*
 	 * A single sg entry may refer to multiple physically contiguous
 	 * pages.  But we still need to process highmem pages individually.
 	 * If highmem is not configured then the bulk of this loop gets
 	 * optimized out.
 	 */
-	size_t left = size;
 	do {
 		size_t len = left;
 		void *vaddr;
 
+		page = pfn_to_page(pfn);
+
 		if (PageHighMem(page)) {
-			if (len + offset > PAGE_SIZE) {
-				if (offset >= PAGE_SIZE) {
-					page += offset / PAGE_SIZE;
-					offset %= PAGE_SIZE;
-				}
+			if (len + offset > PAGE_SIZE)
 				len = PAGE_SIZE - offset;
-			}
 			vaddr = kmap_high_get(page);
 			if (vaddr) {
 				vaddr += offset;
@@ -502,7 +504,7 @@ static void dma_cache_maint_page(struct
 			op(vaddr, len, dir);
 		}
 		offset = 0;
-		page++;
+		pfn++;
 		left -= len;
 	} while (left);
 }
author maintainer
#6 lore raw

PATCH 6/15 Bluetooth: Fix sending HCI commands after reset

In reply to a message not in the archive

3.0-stable review patch. If anyone has any objections, please let me know.

------------------

From: Szymon Janc <[email protected]>

commit dbccd791a3fbbdac12c33834b73beff3984988e9 upstream.

After sending reset command wait for its command complete event before sending next command. Some chips sends CC event for command received before reset if reset was send before chip replied with CC.

This is also required by specification that host shall not send additional HCI commands before receiving CC for reset.

< HCI Command: Reset (0x03|0x0003) plen 0 [hci0] 18.404612

Quoted 1 line

HCI Event: Command Complete (0x0e) plen 4 [hci0] 18.405850

      Write Extended Inquiry Response (0x03|0x0052) ncmd 1
        Status: Success (0x00)

< HCI Command: Read Local Supported Features (0x04|0x0003) plen 0 [hci0] 18.406079

Quoted 1 line

HCI Event: Command Complete (0x0e) plen 4 [hci0] 18.407864

      Reset (0x03|0x0003) ncmd 1
        Status: Success (0x00)

< HCI Command: Read Local Supported Features (0x04|0x0003) plen 0 [hci0] 18.408062

Quoted 1 line

HCI Event: Command Complete (0x0e) plen 12 [hci0] 18.408835

---
 net/bluetooth/hci_event.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
net/bluetooth/hci_event.c +1 -1
@@ -1823,7 +1823,7 @@ static inline void hci_cmd_complete_evt(
 	if (ev->opcode != HCI_OP_NOP)
 		del_timer(&hdev->cmd_timer);
 
-	if (ev->ncmd) {
+	if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
 		atomic_set(&hdev->cmd_cnt, 1);
 		if (!skb_queue_empty(&hdev->cmd_q))
 			tasklet_schedule(&hdev->cmd_task);
author maintainer
#7 lore raw

PATCH 7/15 ath9k_htc: Fix memory leak

In reply to a message not in the archive

3.0-stable review patch. If anyone has any objections, please let me know.

------------------

From: Sujith Manoharan <[email protected]>

commit 0981c3b24ef664f5611008a6e6d0622fac6d892b upstream.

SKBs that are allocated in the HTC layer do not have callbacks registered and hence ended up not being freed, Fix this by freeing them properly in the TX completion routine.

---
 drivers/net/wireless/ath/ath9k/htc_hst.c |    2 ++
 1 file changed, 2 insertions(+)
drivers/net/wireless/ath/ath9k/htc_hst.c +2 -0
@@ -342,6 +342,8 @@ void ath9k_htc_txcompletion_cb(struct ht
 			endpoint->ep_callbacks.tx(endpoint->ep_callbacks.priv,
 						  skb, htc_hdr->endpoint_id,
 						  txok);
+		} else {
+			kfree_skb(skb);
 		}
 	}
 
author maintainer
#8 lore raw

PATCH 8/15 ath9k: fix double-free bug on beacon generate failure

In reply to a message not in the archive

3.0-stable review patch. If anyone has any objections, please let me know.

------------------

From: Felix Fietkau <[email protected]>

commit 1adb2e2b5f85023d17eb4f95386a57029df27c88 upstream.

When the next beacon is sent, the ath_buf from the previous run is reused. If getting a new beacon from mac80211 fails, bf->bf_mpdu is not reset, yet the skb is freed, leading to a double-free on the next beacon tx attempt, resulting in a system crash.

---
 drivers/net/wireless/ath/ath9k/beacon.c |    1 +
 1 file changed, 1 insertion(+)
drivers/net/wireless/ath/ath9k/beacon.c +1 -0
@@ -159,6 +159,7 @@ static struct ath_buf *ath_beacon_genera
 				 skb->len, DMA_TO_DEVICE);
 		dev_kfree_skb_any(skb);
 		bf->bf_buf_addr = 0;
+		bf->bf_mpdu = NULL;
 	}
 
 	/* Get a new beacon from mac80211 */
author maintainer
#9 lore raw

PATCH 9/15 ALSA: usb-audio: fix invalid length check for RME and other UAC 2 devices

In reply to a message not in the archive

3.0-stable review patch. If anyone has any objections, please let me know.

------------------

From: Clemens Ladisch <[email protected]>

commit d56268fb108c7c21e19933588ca4d94652585183 upstream.

Commit 23caaf19b11e (ALSA: usb-mixer: Add support for Audio Class v2.0) forgot to adjust the length check for UAC 2.0 feature unit descriptors. This would make the code abort on encountering a feature unit without per-channel controls, and thus prevented the driver to work with any device having such a unit, such as the RME Babyface or Fireface UCX.

---
 sound/usb/mixer.c |   17 ++++++++++++-----
 1 file changed, 12 insertions(+), 5 deletions(-)
sound/usb/mixer.c +12 -5
@@ -1238,16 +1238,23 @@ static int parse_audio_feature_unit(stru
 		}
 		channels = (hdr->bLength - 7) / csize - 1;
 		bmaControls = hdr->bmaControls;
+		if (hdr->bLength < 7 + csize) {
+			snd_printk(KERN_ERR "usbaudio: unit %u: "
+				   "invalid UAC_FEATURE_UNIT descriptor\n",
+				   unitid);
+			return -EINVAL;
+		}
 	} else {
 		struct uac2_feature_unit_descriptor *ftr = _ftr;
 		csize = 4;
 		channels = (hdr->bLength - 6) / 4 - 1;
 		bmaControls = ftr->bmaControls;
-	}
-
-	if (hdr->bLength < 7 || !csize || hdr->bLength < 7 + csize) {
-		snd_printk(KERN_ERR "usbaudio: unit %u: invalid UAC_FEATURE_UNIT descriptor\n", unitid);
-		return -EINVAL;
+		if (hdr->bLength < 6 + csize) {
+			snd_printk(KERN_ERR "usbaudio: unit %u: "
+				   "invalid UAC_FEATURE_UNIT descriptor\n",
+				   unitid);
+			return -EINVAL;
+		}
 	}
 
 	/* parse the source unit */
author maintainer
#10 lore raw

PATCH 10/15 EDAC: Test correct variable in ->store function

In reply to a message not in the archive

3.0-stable review patch. If anyone has any objections, please let me know.

------------------

From: Dan Carpenter <[email protected]>

commit 8024c4c0b1057d1cd811fc9c3f88f81de9729fcd upstream.

We're testing for ->show but calling ->store().

---
 drivers/edac/edac_pci_sysfs.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/edac/edac_pci_sysfs.c +1 -1
@@ -257,7 +257,7 @@ static ssize_t edac_pci_dev_store(struct
 	struct edac_pci_dev_attribute *edac_pci_dev;
 	edac_pci_dev = (struct edac_pci_dev_attribute *)attr;
 
-	if (edac_pci_dev->show)
+	if (edac_pci_dev->store)
 		return edac_pci_dev->store(edac_pci_dev->value, buffer, count);
 	return -EIO;
 }
author maintainer
#11 lore raw

PATCH 11/15 Bluetooth: Fix incorrect strncpy() in hidp_setup_hid()

In reply to a message not in the archive

3.0-stable review patch. If anyone has any objections, please let me know.

------------------

From: Anderson Lizardo <[email protected]>

commit 0a9ab9bdb3e891762553f667066190c1d22ad62b upstream.

The length parameter should be sizeof(req->name) - 1 because there is no guarantee that string provided by userspace will contain the trailing '\0'.

Can be easily reproduced by manually setting req->name to 128 non-zero bytes prior to ioctl(HIDPCONNADD) and checking the device name setup on input subsystem:

$ cat /sys/devices/pnp0/00\:04/tty/ttyS0/hci0/hci0\:1/input8/name
AAAAAA[...]AAAAAAAAf0:af:f0:af:f0:af

("f0:af:f0:af:f0:af" is the device bluetooth address, taken from "phys" field in struct hid_device due to overflow.)

---
 net/bluetooth/hidp/core.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
net/bluetooth/hidp/core.c +1 -1
@@ -934,7 +934,7 @@ static int hidp_setup_hid(struct hidp_se
 	hid->version = req->version;
 	hid->country = req->country;
 
-	strncpy(hid->name, req->name, 128);
+	strncpy(hid->name, req->name, sizeof(req->name) - 1);
 	strncpy(hid->phys, batostr(&bt_sk(session->ctrl_sock->sk)->src), 64);
 	strncpy(hid->uniq, batostr(&bt_sk(session->ctrl_sock->sk)->dst), 64);
 
author maintainer
#12 lore raw

PATCH 12/15 smp: Fix SMP function call empty cpu mask race

In reply to a message not in the archive

3.0-stable review patch. If anyone has any objections, please let me know.

------------------

From: Wang YanQing <[email protected]>

commit f44310b98ddb7f0d06550d73ed67df5865e3eda5 upstream.

I get the following warning every day with v3.7, once or twice a day:

  [ 2235.186027] WARNING: at /mnt/sda7/kernel/linux/arch/x86/kernel/apic/ipi.c:109 default_send_IPI_mask_logical+0x2f/0xb8()

As explained by Linus as well:

 |
 | Once we've done the "list_add_rcu()" to add it to the
 | queue, we can have (another) IPI to the target CPU that can
 | now see it and clear the mask.
 |
 | So by the time we get to actually send the IPI, the mask might
 | have been cleared by another IPI.
 |

This patch also fixes a system hang problem, if the data->cpumask gets cleared after passing this point:

if (WARN_ONCE(!mask, "empty IPI mask"))
return;

then the problem in commit 83d349f35e1a ("x86: don't send an IPI to the empty set of CPU's") will happen again.

---
 kernel/smp.c |   13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)
kernel/smp.c +12 -1
@@ -31,6 +31,7 @@ struct call_function_data {
 	struct call_single_data	csd;
 	atomic_t		refs;
 	cpumask_var_t		cpumask;
+	cpumask_var_t		cpumask_ipi;
 };
 
 static DEFINE_PER_CPU_SHARED_ALIGNED(struct call_function_data, cfd_data);
@@ -54,6 +55,9 @@ hotplug_cfd(struct notifier_block *nfb,
 		if (!zalloc_cpumask_var_node(&cfd->cpumask, GFP_KERNEL,
 				cpu_to_node(cpu)))
 			return notifier_from_errno(-ENOMEM);
+		if (!zalloc_cpumask_var_node(&cfd->cpumask_ipi, GFP_KERNEL,
+				cpu_to_node(cpu)))
+			return notifier_from_errno(-ENOMEM);
 		break;
 
 #ifdef CONFIG_HOTPLUG_CPU
@@ -63,6 +67,7 @@ hotplug_cfd(struct notifier_block *nfb,
 	case CPU_DEAD:
 	case CPU_DEAD_FROZEN:
 		free_cpumask_var(cfd->cpumask);
+		free_cpumask_var(cfd->cpumask_ipi);
 		break;
 #endif
 	};
@@ -524,6 +529,12 @@ void smp_call_function_many(const struct
 		return;
 	}
 
+	/*
+	 * After we put an entry into the list, data->cpumask
+	 * may be cleared again when another CPU sends another IPI for
+	 * a SMP function call, so data->cpumask will be zero.
+	 */
+	cpumask_copy(data->cpumask_ipi, data->cpumask);
 	raw_spin_lock_irqsave(&call_function.lock, flags);
 	/*
 	 * Place entry at the _HEAD_ of the list, so that any cpu still
@@ -547,7 +558,7 @@ void smp_call_function_many(const struct
 	smp_mb();
 
 	/* Send a message to all CPUs in the map */
-	arch_send_call_function_ipi_mask(data->cpumask);
+	arch_send_call_function_ipi_mask(data->cpumask_ipi);
 
 	/* Optionally wait for the CPUs to complete */
 	if (wait)
author maintainer
#13 lore raw

PATCH 13/15 x86/msr: Add capabilities check

In reply to a message not in the archive

3.0-stable review patch. If anyone has any objections, please let me know.

------------------

From: Alan Cox <[email protected]>

commit c903f0456bc69176912dee6dd25c6a66ee1aed00 upstream.

At the moment the MSR driver only relies upon file system checks. This means that anything as root with any capability set can write to MSRs. Historically that wasn't very interesting but on modern processors the MSRs are such that writing to them provides several ways to execute arbitary code in kernel space. Sample code and documentation on doing this is circulating and MSR attacks are used on Windows 64bit rootkits already.

In the Linux case you still need to be able to open the device file so the impact is fairly limited and reduces the security of some capability and security model based systems down towards that of a generic "root owns the box" setup.

Therefore they should require CAP_SYS_RAWIO to prevent an elevation of capabilities. The impact of this is fairly minimal on most setups because they don't have heavy use of capabilities. Those using SELinux, SMACK or AppArmor rules might want to consider if their rulesets on the MSR driver could be tighter.

---
 arch/x86/kernel/msr.c |    3 +++
 1 file changed, 3 insertions(+)
arch/x86/kernel/msr.c +3 -0
@@ -175,6 +175,9 @@ static int msr_open(struct inode *inode,
 	unsigned int cpu;
 	struct cpuinfo_x86 *c;
 
+	if (!capable(CAP_SYS_RAWIO))
+		return -EPERM;
+
 	cpu = iminor(file->f_path.dentry->d_inode);
 	if (cpu >= nr_cpu_ids || !cpu_online(cpu))
 		return -ENXIO;	/* No such CPU */
author maintainer
#14 lore raw

PATCH 14/15 efi, x86: Pass a proper identity mapping in efi_call_phys_prelog

In reply to a message not in the archive

3.0-stable review patch. If anyone has any objections, please let me know.

------------------

From: Nathan Zimmer <[email protected]>

commit b8f2c21db390273c3eaf0e5308faeaeb1e233840 upstream.

Update efi_call_phys_prelog to install an identity mapping of all available memory. This corrects a bug on very large systems with more then 512 GB in which bios would not be able to access addresses above not in the mapping.

The result is a crash that looks much like this.

BUG: unable to handle kernel paging request at 000000effd870020
IP: [<0000000078bce331>] 0x78bce330
PGD 0
Oops: 0000 [#1] SMP
Modules linked in:
CPU 0
Pid: 0, comm: swapper/0 Tainted: G        W    3.8.0-rc1-next-20121224-medusa_ntz+ #2 Intel Corp. Stoutland Platform
RIP: 0010:[<0000000078bce331>]  [<0000000078bce331>] 0x78bce330
RSP: 0000:ffffffff81601d28  EFLAGS: 00010006
RAX: 0000000078b80e18 RBX: 0000000000000004 RCX: 0000000000000004
RDX: 0000000078bcf958 RSI: 0000000000002400 RDI: 8000000000000000
RBP: 0000000078bcf760 R08: 000000effd870000 R09: 0000000000000000
R10: 0000000000000000 R11: 00000000000000c3 R12: 0000000000000030
R13: 000000effd870000 R14: 0000000000000000 R15: ffff88effd870000
FS:  0000000000000000(0000) GS:ffff88effe400000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 000000effd870020 CR3: 000000000160c000 CR4: 00000000000006b0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
Process swapper/0 (pid: 0, threadinfo ffffffff81600000, task ffffffff81614400)
Stack:
 0000000078b80d18 0000000000000004 0000000078bced7b ffff880078b81fff
 0000000000000000 0000000000000082 0000000078bce3a8 0000000000002400
 0000000060000202 0000000078b80da0 0000000078bce45d ffffffff8107cb5a
Call Trace:
 [<ffffffff8107cb5a>] ? on_each_cpu+0x77/0x83
 [<ffffffff8102f4eb>] ? change_page_attr_set_clr+0x32f/0x3ed
 [<ffffffff81035946>] ? efi_call4+0x46/0x80
 [<ffffffff816c5abb>] ? efi_enter_virtual_mode+0x1f5/0x305
 [<ffffffff816aeb24>] ? start_kernel+0x34a/0x3d2
 [<ffffffff816ae5ed>] ? repair_env_string+0x60/0x60
 [<ffffffff816ae2be>] ? x86_64_start_reservations+0xba/0xc1
 [<ffffffff816ae120>] ? early_idt_handlers+0x120/0x120
 [<ffffffff816ae419>] ? x86_64_start_kernel+0x154/0x163
Code:  Bad RIP value.
RIP  [<0000000078bce331>] 0x78bce330
 RSP <ffffffff81601d28>
CR2: 000000effd870020
---[ end trace ead828934fef5eab ]---
---
 arch/x86/platform/efi/efi_64.c |   22 +++++++++++++++++-----
 1 file changed, 17 insertions(+), 5 deletions(-)
arch/x86/platform/efi/efi_64.c +17 -5
@@ -38,7 +38,7 @@
 #include <asm/cacheflush.h>
 #include <asm/fixmap.h>
 
-static pgd_t save_pgd __initdata;
+static pgd_t *save_pgd __initdata;
 static unsigned long efi_flags __initdata;
 
 static void __init early_code_mapping_set_exec(int executable)
@@ -61,12 +61,20 @@ static void __init early_code_mapping_se
 void __init efi_call_phys_prelog(void)
 {
 	unsigned long vaddress;
+	int pgd;
+	int n_pgds;
 
 	early_code_mapping_set_exec(1);
 	local_irq_save(efi_flags);
-	vaddress = (unsigned long)__va(0x0UL);
-	save_pgd = *pgd_offset_k(0x0UL);
-	set_pgd(pgd_offset_k(0x0UL), *pgd_offset_k(vaddress));
+
+	n_pgds = DIV_ROUND_UP((max_pfn << PAGE_SHIFT), PGDIR_SIZE);
+	save_pgd = kmalloc(n_pgds * sizeof(pgd_t), GFP_KERNEL);
+
+	for (pgd = 0; pgd < n_pgds; pgd++) {
+		save_pgd[pgd] = *pgd_offset_k(pgd * PGDIR_SIZE);
+		vaddress = (unsigned long)__va(pgd * PGDIR_SIZE);
+		set_pgd(pgd_offset_k(pgd * PGDIR_SIZE), *pgd_offset_k(vaddress));
+	}
 	__flush_tlb_all();
 }
 
@@ -75,7 +83,11 @@ void __init efi_call_phys_epilog(void)
 	/*
 	 * After the lock is released, the original page table is restored.
 	 */
-	set_pgd(pgd_offset_k(0x0UL), save_pgd);
+	int pgd;
+	int n_pgds = DIV_ROUND_UP((max_pfn << PAGE_SHIFT) , PGDIR_SIZE);
+	for (pgd = 0; pgd < n_pgds; pgd++)
+		set_pgd(pgd_offset_k(pgd * PGDIR_SIZE), save_pgd[pgd]);
+	kfree(save_pgd);
 	__flush_tlb_all();
 	local_irq_restore(efi_flags);
 	early_code_mapping_set_exec(0);
author maintainer
#15 lore raw

PATCH 15/15 x86/Sandy Bridge: Sandy Bridge workaround depends on CONFIG_PCI

In reply to a message not in the archive

3.0-stable review patch. If anyone has any objections, please let me know.

------------------

From: "H. Peter Anvin" <[email protected]>

commit e43b3cec711a61edf047adf6204d542f3a659ef8 upstream.

early_pci_allowed() and read_pci_config_16() are only available if CONFIG_PCI is defined.

---
 arch/x86/kernel/setup.c |    2 ++
 1 file changed, 2 insertions(+)
arch/x86/kernel/setup.c +2 -0
@@ -633,6 +633,7 @@ static unsigned reserve_low = CONFIG_X86
 
 static bool __init snb_gfx_workaround_needed(void)
 {
+#ifdef CONFIG_PCI
 	int i;
 	u16 vendor, devid;
 	static const u16 snb_ids[] = {
@@ -657,6 +658,7 @@ static bool __init snb_gfx_workaround_ne
 	for (i = 0; i < ARRAY_SIZE(snb_ids); i++)
 		if (devid == snb_ids[i])
 			return true;
+#endif
 
 	return false;
 }