summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gm206/bios_gm206.c
diff options
context:
space:
mode:
authorTerje Bergstrom <tbergstrom@nvidia.com>2016-08-31 18:12:10 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2016-09-21 18:14:02 -0400
commit2d593e737ddf4a81721dc6da81aa3f7fbe783630 (patch)
tree727c8d2903b486db5c2fb2894dd97636ebcc98bc /drivers/gpu/nvgpu/gm206/bios_gm206.c
parentf937b42672c8752c322a946e8e1fb631acc5229a (diff)
gpu: nvgpu: Add error checks on VBIOS read
Add error checks to prevent loading a random image as VBIOS. JIRA DNVGPU-134 Change-Id: Ia3efd0ed743b6a7661707612828a795802e96cd9 Signed-off-by: Terje Bergstrom <tbergstrom@nvidia.com> Reviewed-on: http://git-master/r/1211613 (cherry picked from commit ffa2b6df3f11d6c63b1e4337bd7d989932bdfce8) Reviewed-on: http://git-master/r/1223844 GVS: Gerrit_Virtual_Submit
Diffstat (limited to 'drivers/gpu/nvgpu/gm206/bios_gm206.c')
-rw-r--r--drivers/gpu/nvgpu/gm206/bios_gm206.c23
1 files changed, 21 insertions, 2 deletions
diff --git a/drivers/gpu/nvgpu/gm206/bios_gm206.c b/drivers/gpu/nvgpu/gm206/bios_gm206.c
index 7159ef83..6caecb32 100644
--- a/drivers/gpu/nvgpu/gm206/bios_gm206.c
+++ b/drivers/gpu/nvgpu/gm206/bios_gm206.c
@@ -27,6 +27,8 @@
27#define BIT_HEADER_SIGNATURE 0x00544942 27#define BIT_HEADER_SIGNATURE 0x00544942
28#define BIOS_SIZE 0x40000 28#define BIOS_SIZE 0x40000
29#define NV_PCFG 0x88000 29#define NV_PCFG 0x88000
30#define PCI_EXP_ROM_SIG 0xaa55
31#define PCI_EXP_ROM_SIG_NV 0x4e56
30#define PMU_BOOT_TIMEOUT_DEFAULT 100 /* usec */ 32#define PMU_BOOT_TIMEOUT_DEFAULT 100 /* usec */
31#define PMU_BOOT_TIMEOUT_MAX 2000000 /* usec */ 33#define PMU_BOOT_TIMEOUT_MAX 2000000 /* usec */
32 34
@@ -183,7 +185,7 @@ struct pci_ext_data_struct {
183 u8 flags; 185 u8 flags;
184} __packed; 186} __packed;
185 187
186static void gm206_bios_parse_rom(struct gk20a *g) 188static int gm206_bios_parse_rom(struct gk20a *g)
187{ 189{
188 int offset = 0; 190 int offset = 0;
189 int last = 0; 191 int last = 0;
@@ -198,6 +200,12 @@ static void gm206_bios_parse_rom(struct gk20a *g)
198 pci_rom->sig, pci_rom->pci_data_struct_ptr, 200 pci_rom->sig, pci_rom->pci_data_struct_ptr,
199 pci_rom->size_of_block); 201 pci_rom->size_of_block);
200 202
203 if (pci_rom->sig != PCI_EXP_ROM_SIG &&
204 pci_rom->sig != PCI_EXP_ROM_SIG_NV) {
205 gk20a_err(g->dev, "invalid VBIOS signature");
206 return -EINVAL;
207 }
208
201 pci_data = 209 pci_data =
202 (struct pci_data_struct *) 210 (struct pci_data_struct *)
203 &g->bios.data[offset + pci_rom->pci_data_struct_ptr]; 211 &g->bios.data[offset + pci_rom->pci_data_struct_ptr];
@@ -233,6 +241,8 @@ static void gm206_bios_parse_rom(struct gk20a *g)
233 last = pci_data->last_image; 241 last = pci_data->last_image;
234 } 242 }
235 } 243 }
244
245 return 0;
236} 246}
237 247
238static void gm206_bios_parse_nvinit_ptrs(struct gk20a *g, int offset) 248static void gm206_bios_parse_nvinit_ptrs(struct gk20a *g, int offset)
@@ -698,6 +708,7 @@ static int gm206_bios_init(struct gk20a *g)
698 struct gk20a_platform *platform = dev_get_drvdata(g->dev); 708 struct gk20a_platform *platform = dev_get_drvdata(g->dev);
699 struct dentry *d; 709 struct dentry *d;
700 int err; 710 int err;
711 bool found = 0;
701 712
702 gk20a_dbg_fn(""); 713 gk20a_dbg_fn("");
703 g->bios.data = kzalloc(BIOS_SIZE, GFP_KERNEL); 714 g->bios.data = kzalloc(BIOS_SIZE, GFP_KERNEL);
@@ -718,15 +729,23 @@ static int gm206_bios_init(struct gk20a *g)
718 gk20a_writel(g, NV_PCFG + xve_rom_ctrl_r(), 729 gk20a_writel(g, NV_PCFG + xve_rom_ctrl_r(),
719 xve_rom_ctrl_rom_shadow_enabled_f()); 730 xve_rom_ctrl_rom_shadow_enabled_f());
720 731
721 gm206_bios_parse_rom(g); 732 err = gm206_bios_parse_rom(g);
733 if (err)
734 return err;
735
722 gk20a_dbg_info("read bios"); 736 gk20a_dbg_info("read bios");
723 for (i = 0; i < BIOS_SIZE; i++) { 737 for (i = 0; i < BIOS_SIZE; i++) {
724 if (gm206_bios_rdu16(g, i) == BIT_HEADER_ID && 738 if (gm206_bios_rdu16(g, i) == BIT_HEADER_ID &&
725 gm206_bios_rdu32(g, i+2) == BIT_HEADER_SIGNATURE) { 739 gm206_bios_rdu32(g, i+2) == BIT_HEADER_SIGNATURE) {
726 gm206_bios_parse_bit(g, i); 740 gm206_bios_parse_bit(g, i);
741 found = true;
727 } 742 }
728 } 743 }
729 744
745 if (!found) {
746 gk20a_err(g->dev, "no valid VBIOS found");
747 return -EINVAL;
748 }
730 g->bios_blob.data = g->bios.data; 749 g->bios_blob.data = g->bios.data;
731 g->bios_blob.size = BIOS_SIZE; 750 g->bios_blob.size = BIOS_SIZE;
732 751